美文网首页
弱引用管理相关

弱引用管理相关

作者: 小行为 | 来源:发表于2018-11-18 17:25 被阅读11次
屏幕快照 2018-11-17 下午11.00.18.png

objc_initweak() 函数具体实现是怎样的?

添加weak 变量


屏幕快照 2018-11-17 下午11.02.11.png
id
objc_initWeak(id *location, id newObj)
{
    if (!newObj) {
        *location = nil;
        return nil;
    }

    return storeWeak<false/*old*/, true/*new*/, true/*crash*/>
        (location, (objc_object*)newObj);
}

template <bool HaveOld, bool HaveNew, bool CrashIfDeallocating>
static id 
storeWeak(id *location, objc_object *newObj)
{
    assert(HaveOld  ||  HaveNew);
    if (!HaveNew) assert(newObj == nil);

    Class previouslyInitializedClass = nil;
    id oldObj;
    SideTable *oldTable;
    SideTable *newTable;

    // Acquire locks for old and new values.
    // Order by lock address to prevent lock ordering problems. 
    // Retry if the old value changes underneath us.
 retry:
    if (HaveOld) {
        oldObj = *location;
        oldTable = &SideTables()[oldObj];
    } else {
        oldTable = nil;
    }
    if (HaveNew) {
        newTable = &SideTables()[newObj];
    } else {
        newTable = nil;
    }

    SideTable::lockTwo<HaveOld, HaveNew>(oldTable, newTable);

    if (HaveOld  &&  *location != oldObj) {
        SideTable::unlockTwo<HaveOld, HaveNew>(oldTable, newTable);
        goto retry;
    }

    // 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;
        }
    }

    // Clean up old value, if any.
    if (HaveOld) {
        weak_unregister_no_lock(&oldTable->weak_table, oldObj, location);
    }

    // Assign new value, if any.
    if (HaveNew) {
        newObj = (objc_object *)weak_register_no_lock(&newTable->weak_table, 
                                                      (id)newObj, location, 
                                                      CrashIfDeallocating);
        // weak_register_no_lock returns nil if weak store should be rejected

        // Set is-weakly-referenced bit in refcount table.
        if (newObj  &&  !newObj->isTaggedPointer()) {
            newObj->setWeaklyReferenced_nolock();
        }

        // Do not set *location anywhere else. That would introduce a race.
        *location = (id)newObj;
    }
    else {
        // No new value. The storage is not changed.
    }
    
    SideTable::unlockTwo<HaveOld, HaveNew>(oldTable, newTable);

    return (id)newObj;
}

 

添加weak 变量流程:
一个被声明 __weak 变量的对象指针 经过 objc_initweak()经过一系列函数调用栈最终在 weak_register_no_lock()函数进行弱引用变量添加,添加位置是通过哈希算法来进行位置查找,如果经过查找对应位置有当前对象所对应的弱引用数组,就把新的弱引用变量添加到数组当中 ,没有新创建弱引用数组第一位 其他添加为nil

清除weak 变量流程:
当一个对象被dealloc 执行 weka_clear_no_lock(),再函数内部根据当前对象指针查找弱引用表,把当前对象相对应的弱引用都取出是个数组,遍历数组分别置为nil

相关文章

  • 弱引用管理相关

    objc_initweak() 函数具体实现是怎样的? 添加weak 变量 添加weak 变量流程:一个被声明 _...

  • 内存管理相关面试问题

    本文主讲内存管理相关面试问题,包括内存布局、内存管理方案、数据结构、ARC&MRC、引用计数管理、弱引用管理、自动...

  • [iOS面试]第4章 内存管理相关面试问题

    本文主讲内存管理相关面试问题,包括内存布局、内存管理方案、数据结构、ARC&MRC、引用计数管理、弱引用管理、自动...

  • iOS Runtime

    runtime数据结构 id = objc_objectisa_t关于isa草错相关弱引用相关关联对象相关内存管理...

  • iOS中弱引用管理相关问题

    关于弱引用在工作和面试中都会经常遇到,那么这里我就两个问题说一下弱引用管理。 weak变量是怎样添加到弱引用表中的...

  • 2022-11-17 06内存管理

    引用计数管理 引用计数管理 clearDeallocating() 弱引用管理 自动释放池 1.是以栈为结点,通过...

  • Swift进阶06:内存管理 & Runtime

    本文主要介绍Swift中的内存管理,涉及引用计数、弱引用、强引用、循环引用、Runtime等 内存管理 - 强引用...

  • OC常用宏定义

    测试输出 Log 屏幕相关 系统相关 定义弱引用、强引用 定义警告宏 颜色宏 其他宏

  • Swift进阶 05:内存管理 & Runtime

    本文主要介绍Swift中的内存管理,涉及引用计数、弱引用、强引用、循环引用与Runtime等。 内存管理-强引用 ...

  • 内存管理-弱引用管理

    一个weak变量是怎样被添加到弱引用表当中的?可以通过弱引用对象进行哈希算法的计算,然后计算查找它对应的位置 下面...

网友评论

      本文标题:弱引用管理相关

      本文链接:https://www.haomeiwen.com/subject/jbqwfqtx.html