iOS initialize

initialize 方法会在类第一次接收到消息时调用比如
[NSobject alloc]
调用顺序
先调用父类的initialize在调用子类的initialize
(先初始化父类,在初始化子类,每个类都只会初始化一次)

initialize和load区别的是initialize是通过objc——msgsend调用的所以有以下特点
1、如果子类没有实现initialize会调用父类的initialize(所以父类的initialize可能会被调用多次)
2、如果分类实现了initialize.就覆盖类本身的initialize调用

void initializeNonMetaClass(Class cls)
{
ASSERT(!cls->isMetaClass());

Class supercls;
bool reallyInitialize = NO;

// Make sure super is done initializing BEFORE beginning to initialize cls.
// See note about deadlock above.
//取得父类
supercls = cls->getSuperclass();
//如果有父类并且父类没有实例化先初始化父类
if (supercls  &&  !supercls->isInitialized()) {
    //通过递归方式传入父类
    initializeNonMetaClass(supercls);
}

// Try to atomically set CLS_INITIALIZING.
SmallVector<_objc_willInitializeClassCallback, 1> localWillInitializeFuncs;
{
    monitor_locker_t lock(classInitLock);
    if (!cls->isInitialized() && !cls->isInitializing()) {
        cls->setInitializing();
        reallyInitialize = YES;

        // Grab a copy of the will-initialize funcs with the lock held.
        localWillInitializeFuncs.initFrom(willInitializeFuncs);
    }
}

if (reallyInitialize) {
    // We successfully set the CLS_INITIALIZING bit. Initialize the class.
    
    // Record that we're initializing this class so we can message it.
    _setThisThreadIsInitializingClass(cls);

    if (MultithreadedForkChild) {
        // LOL JK we don't really call +initialize methods after fork().
        performForkChildInitialize(cls, supercls);
        return;
    }
    
    for (auto callback : localWillInitializeFuncs)
        callback.f(callback.context, cls);

    // Send the +initialize message.
    // Note that +initialize is sent to the superclass (again) if 
    // this class doesn't implement +initialize. 2157218
    if (PrintInitializing) {
        _objc_inform("INITIALIZE: thread %p: calling +[%s initialize]",
                     objc_thread_self(), cls->nameForLogging());
    }

    // Exceptions: A +initialize call that throws an exception 
    // is deemed to be a complete and successful +initialize.
    //
    // Only __OBJC2__ adds these handlers. !__OBJC2__ has a
    // bootstrapping problem of this versus CF's call to
    // objc_exception_set_functions().
#if __OBJC2__
    @try
#endif
    {
       //第一次是传入父类
       //第二次是传入当前的类
        callInitialize(cls);

        if (PrintInitializing) {
            _objc_inform("INITIALIZE: thread %p: finished +[%s initialize]",
                         objc_thread_self(), cls->nameForLogging());
        }
    }
#if __OBJC2__
    @catch (...) {
        if (PrintInitializing) {
            _objc_inform("INITIALIZE: thread %p: +[%s initialize] "
                         "threw an exception",
                         objc_thread_self(), cls->nameForLogging());
        }
        @throw;
    }
    @finally
#endif
    {
        // Done initializing.
        lockAndFinishInitializing(cls, supercls);
    }
    return;
}

else if (cls->isInitializing()) {
    // We couldn't set INITIALIZING because INITIALIZING was already set.
    // If this thread set it earlier, continue normally.
    // If some other thread set it, block until initialize is done.
    // It's ok if INITIALIZING changes to INITIALIZED while we're here, 
    //   because we safely check for INITIALIZED inside the lock 
    //   before blocking.
    if (_thisThreadIsInitializingClass(cls)) {
        return;
    } else if (!MultithreadedForkChild) {
        waitForInitializeToComplete(cls);
        return;
    } else {
        // We're on the child side of fork(), facing a class that
        // was initializing by some other thread when fork() was called.
        _setThisThreadIsInitializingClass(cls);
        performForkChildInitialize(cls, supercls);
    }
}

else if (cls->isInitialized()) {
    // Set CLS_INITIALIZING failed because someone else already 
    //   initialized the class. Continue normally.
    // NOTE this check must come AFTER the ISINITIALIZING case.
    // Otherwise: Another thread is initializing this class. ISINITIALIZED 
    //   is false. Skip this clause. Then the other thread finishes 
    //   initialization and sets INITIALIZING=no and INITIALIZED=yes. 
    //   Skip the ISINITIALIZING clause. Die horribly.
    return;
}

else {
    // We shouldn't be here. 
    _objc_fatal("thread-safe class init in objc runtime is buggy!");
}
}

你可能感兴趣的:(iOS initialize)