iOS-Source-Probe icon indicating copy to clipboard operation
iOS-Source-Probe copied to clipboard

关于storeWeak方法中为什么会和初始化机制引发死锁问题

Open ParanoiaWan opened this issue 7 years ago • 2 comments


// Prevent a deadlock between the weak reference machinery
    // and the +initialize machinery by ensuring that no 
    // weakly-referenced object has an un-+initialized isa.
    if (haveNew  &&  newObj) {
        Class cls = newObj->getIsa();
        if (cls != previouslyInitializedClass  &&  
            !((objc_class *)cls)->isInitialized()) 
        {
            SideTable::unlockTwo<haveOld, haveNew>(oldTable, newTable);
            _class_initialize(_class_getNonMetaClass(cls, (id)newObj));

            // If this class is finished with +initialize then we're good.
            // If this class is still running +initialize on this thread 
            // (i.e. +initialize called storeWeak on an instance of itself)
            // then we may proceed but it will appear initializing and 
            // not yet initialized to the check above.
            // Instead set previouslyInitializedClass to recognize it on retry.
            previouslyInitializedClass = cls;

            goto retry;
        }
    }

ParanoiaWan avatar Jul 27 '18 10:07 ParanoiaWan

isInitialized这个方法是+initialized的判断方法,来判断当前类是否初始化过。 因为+initialize方法实际上是在alloc方法之前调用的。很有可能会发生+initialize 中调用了 storeWeak 方法,而在 storeWeak 方法中 weak_register_no_lock 方法中用到对象的 isa 还没有初始化完成的情况

BiBoyang avatar Nov 17 '18 06:11 BiBoyang

isInitialized这个方法是+initialized的判断方法,来判断当前类是否初始化过。 因为+initialize方法实际上是在alloc方法之前调用的。很有可能会发生+initialize 中调用了 storeWeak 方法,而在 storeWeak 方法中 weak_register_no_lock 方法中用到对象的 isa 还没有初始化完成的情况

但是源码是这样的:

Class cls = newObj->getIsa();
if (cls != previouslyInitializedClass  &&  
    !((objc_class *)cls)->isInitialized()) 
{
    SideTable::unlockTwo<haveOld, haveNew>(oldTable, newTable);
    _class_initialize(_class_getNonMetaClass(cls, (id)newObj));
    previouslyInitializedClass = cls;
    goto retry;
}

newObj 是一个类的实例对象, 已经都有调用 alloc 方法了, 又如何会出现 很有可能会发生+initialize 中调用了 storeWeak 方法,而在 storeWeak 方法中 weak_register_no_lock 方法中用到对象的 isa 还没有初始化完成的情况 这种情况呢? 即对象都已经被初始化, 为什么还会有 对象的 isa 还没有初始化完成的情况 这种情况.

wxiubin avatar Jan 12 '20 09:01 wxiubin