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!");
}
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • [toc] 参考 initialize load code objc4源码解析 思路 既然 +initialize...
    felix6阅读 3,968评论 0 2
  • +initialize方法 +initialize方法会在类第一次接收到objc_msgSend消息时调用 通过递...
    dbmxl阅读 4,377评论 0 0
  •   我们都知道initialize方法只有当类或子类第一次收到消息时才会调用。我们在这个方法里打上断点来看看,比如...
    水煮杰尼龟阅读 5,188评论 0 5
  • 记录一下initialize和load方法的调用时机 问题一 load和initialize哪个更早执行? 1....
    霸_霸霸阅读 2,823评论 0 1
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 128,437评论 2 7

友情链接更多精彩内容