2

随着ARC的出现,一些新的功能可供开发人员使用弱引用的对象。 id objc_loadWeak(id *location)就是其中之一。这个函数接收一个参数,对应于存储弱对象的内存中的一个位置,如果它仍然存在则返回该对象,或者如果它被释放,则返回nilObjective-C运行时如何知道弱引用的对象是否还活着?

看来,当一个对象objid objc_storeWeak(id *location, id obj)存储为weak在一个位置locationobj被放在一个“弱图”,以location作为重点。但是,为了检索objobjc_loadWeak不仅可以使用location作为关键字并返回对应于obj的值。它还必须检查obj是否还活着,如果它不在,则返回nil

但是,objc_loadWeak无法尝试读取该对象的保留计数,因为该对象可能已被释放。此外,尽管在相同的文件(NSObject.mm)中执行弱映射objc_storeWeak,objc_loadWeakNSObject类,但是NSObjectdealloc方法不向弱映射发信号通知正被释放的对象正在消失。

那么,Objective-C运行库如何确定一个weak对象是否仍然存在?

回答

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是一个C++类,在NSObject.mm中实现,其中refcnts成员变量完全按照它听起来的样子进行:它保存引用计数。

+0

哦,是的。直到最后,我没有遵循链条。当我到达'object_dispose()'时停止。由于这个函数被放置在另一个文件中,我认为它与弱引用处理无关。非常感谢你! – LuisABOL 2013-02-13 13:53:19

+0

@ LuisAntonioBotelhoO.Leite不客气。 – 2013-02-13 13:54:01