Objective-C运行时如何知道弱引用对象是否仍然存活?

时间:2013-02-13 13:26:36

标签: objective-c automatic-ref-counting weak-references objective-c-runtime

随着ARC的出现,一些新功能可供开发人员使用弱引用对象。 id objc_loadWeak(id *location)就是其中之一。此函数接收一个参数,该参数对应于存储弱对象的内存中的位置,如果该对象仍处于活动状态,则返回该对象;如果已解除分配,则返回nil

似乎当对象obj作为weak存储在location的{​​{1}}位置时,id objc_storeWeak(id *location, id obj)会被置于“弱地图”中,以obj为关键。但是,为了检索locationobj不仅可以使用objc_loadWeak作为关键字并返回与location对应的值。它还必须检查obj是否仍然有效,如果不再存在,则返回obj

但是,nil无法尝试读取对象的保留计数,因为该对象可能已被解除分配。此外,虽然弱地图objc_loadWeakobjc_storeWeakobjc_loadWeak类在同一个文件中实现(NSObject.mm),但NSObject的{​​{1}方法不会向弱映射发信号通知正被解除分配的对象正在消失。

那么,Objective-C运行时如何判断NSObject对象是否还活着?

1 个答案:

答案 0 :(得分:9)

  

NSObject的dealloc方法不会向弱地图发出信号,表示正被解除分配的对象正在消失。

确实如此。

- [NSObject dealloc]

呼叫

_objc_rootDealloc(self);

反过来调用

object_dispose()

反过来调用

objc_destructInstance()

最后调用

objc_clear_deallocating()

最后一个函数如下所示:

    void 
objc_clear_deallocating(id obj) 
{
    assert(obj);
    assert(!UseGC);

    SideTable *table = SideTable::tableForPointer(obj); /* *** THIS LINE *** */

    // clear any weak table items
    // clear extra retain count and deallocating bit
    // (fixme warn or abort if extra retain count == 0 ?)
    OSSpinLockLock(&table->slock);
    if (seen_weak_refs) {
    arr_clear_deallocating(&table->weak_table, obj); /* *** THIS LINE *** */
    }
    table->refcnts.erase(DISGUISE(obj)); /* *** THIS LINE *** */
    OSSpinLockUnlock(&table->slock);
}

三条突出显示的线条具有魔力。 SideTable是在NSObject.mm中实现的C ++类,refcnts成员变量完全按照它的含义执行:它保存引用计数。