Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ParanoiaWan opened this issue Jul 27, 2018 · 2 comments
Assignees

Comments

@ParanoiaWan
Copy link

ParanoiaWan commented Jul 27, 2018

// 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;
        }
    }
@Desgard Desgard self-assigned this Aug 8, 2018
@BiBoyang
Copy link

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

@wxiubin
Copy link

wxiubin commented Jan 12, 2020

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 还没有初始化完成的情况 这种情况.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants