OS X v10.11 beta release notes中,我发现以下内容:



这对我来说没有意义。如果它是非弱引用,那不是强引用吗?因此,NSNotificationCenter仍将是所有者,因此该对象不会取消分配(直到手动取消注册),因此在这种情况下称其为“清零”是毫无意义的。

如果这是指某种__unsafe_unretained引用,那么问题是……那么,NSNotificationCenter如何避免向僵尸发送消息?

最佳答案

答案就在于Objective-C运行时,以及__weak变量的实际工作方式。为了说明,让我们看一下objc_weak.mm:

id
weak_read_no_lock(weak_table_t *weak_table, id *referrer_id)
{
    ...

    if (! referent->ISA()->hasCustomRR()) {
        if (! referent->rootTryRetain()) {
            return nil;
        }
    }
    else {
        BOOL (*tryRetain)(objc_object *, SEL) = (BOOL(*)(objc_object *, SEL))
            object_getMethodImplementation((id)referent,
                                           SEL_retainWeakReference);
        if ((IMP)tryRetain == _objc_msgForward) {
            return nil;
        }
        if (! (*tryRetain)(referent, SEL_retainWeakReference)) {
            return nil;
        }
    }

    return (id)referent;
}

如您所见,当对象使用自定义-retain-release方法时,不能保证它们完全支持弱引用(还要注意,您可以为对象的弱引用使用完全不同的对象,尽管这是另一个主题的主题)时间)。

这是因为弱引用被objc_destructInstance清理,后者调用objc_clearDeallocating,后者调用weak_clear_no_lock

现在,自定义对象实现不需要调用objc_destructInstance,尽管大多数对象会调用它。

因此,运行时允许您实现-allowsWeakReference(和retainWeakReference)方法来禁用对对象的弱引用,在这种情况下,很可能通过在对象上模糊-dealloc将其弱化为零。当然,这是所有实现细节,因此NSNotificationCenter可以采用自己的创新方式来做事,但这是我最好的猜测,而无需尝试反汇编NSNotificationCenter。

关于objective-c - 什么是 "non-weak zeroing reference",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30769262/

10-12 05:39