随着 ARC 的出现,一些新功能可供开发人员使用弱引用对象。 id objc_loadWeak(id *location)
就是其中之一。此函数接收一个参数,该参数对应于存储弱对象的内存位置,如果该对象仍然存在则返回该对象,如果它已被释放则返回 nil
。
似乎当一个对象 obj
以 weak
的形式存储在一个位置 location
with id objc_storeWeak(id *location, id obj)
,obj
被放入一个“弱映射”中,以location
为key。但是,为了检索obj
,objc_loadWeak
不仅可以将location
作为key返回值,对应obj
。它还必须检查 obj
是否仍然存在,如果它不再存在则返回 nil
。
但是,objc_loadWeak
无法尝试读取对象的保留计数,因为对象可能已被释放。此外,虽然弱映射、objc_storeWeak
、objc_loadWeak
和 NSObject
类在同一个文件 (NSObject.mm) 中实现, NSObject
的 dealloc
方法不会向 weak map 发出正在释放的对象即将消失的信号。
那么,Objective-C 运行时如何判断一个weak
对象是否仍然存在?
最佳答案
NSObject's dealloc method doesn't signals to the weak map that the object that is being deallocated is going away.
确实如此。
- [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
成员变量的作用和它听起来的一样:它保存引用计数.
关于objective-c - Objective-C 运行时如何知道弱引用对象是否仍然存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14854635/