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

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

随着 ARC 的出现,一些新功能可供开发人员使用弱引用对象。 id objc_loadWeak(id *location) 就是其中之一。此函数接收一个参数,该参数对应于存储弱对象的内存位置,如果该对象仍然存在则返回该对象,如果它已被释放则返回 nil

似乎当一个对象 objweak 的形式存储在一个位置 location with id objc_storeWeak(id *location, id obj)obj被放入一个“弱映射”中,以location为key。但是,为了检索objobjc_loadWeak不仅可以将location作为key返回值,对应obj 。它还必须检查 obj 是否仍然存在,如果它不再存在则返回 nil

但是,objc_loadWeak 无法尝试读取对象的保留计数,因为对象可能已被释放。此外,虽然弱映射、objc_storeWeakobjc_loadWeakNSObject 类在同一个文件 (NSObject.mm) 中实现, NSObjectdealloc 方法不会向 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/

相关文章:

objective-c - 无法在 NSPopover 中设置内容

iphone - 如何在 iPhone 应用程序中为图像制作动画?

iphone - iOS静态库的向后兼容性

iphone - 检查 NSDictionary 中的键是否为空

ios - 从 Delegate 方法刷新 UITableView Cell UI 按钮图像的问题

ios - 当 ViewController 取消初始化时,UITableView/UIScrollView 委托(delegate)未设置为 nil

objective-c - 在 iOS 6 中学习 ARC 的资源

c# - 我可以创建一个 List<WeakReference<T>> 吗?

c# - 是否可以手动标记/取消标记对象以进行垃圾收集?

java - 有什么方法可以判断方法是否结束或本地方法不再使用?