随着ARC的出现,一些新功能可供开发人员使用弱引用对象。 id objc_loadWeak(id *location)
就是其中之一。此函数接收一个参数,该参数对应于存储弱对象的内存中的位置,如果该对象仍处于活动状态,则返回该对象;如果已解除分配,则返回nil
。
似乎当对象obj
作为weak
存储在location
的{{1}}位置时,id objc_storeWeak(id *location, id obj)
会被置于“弱地图”中,以obj
为关键。但是,为了检索location
,obj
不仅可以使用objc_loadWeak
作为关键字并返回与location
对应的值。它还必须检查obj
是否仍然有效,如果不再存在,则返回obj
。
但是,nil
无法尝试读取对象的保留计数,因为该对象可能已被解除分配。此外,虽然弱地图objc_loadWeak
,objc_storeWeak
和objc_loadWeak
类在同一个文件中实现(NSObject.mm),但NSObject
的{{1}方法不会向弱映射发信号通知正被解除分配的对象正在消失。
那么,Objective-C运行时如何判断NSObject
对象是否还活着?
答案 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
成员变量完全按照它的含义执行:它保存引用计数。