【问题标题】:What is a "non-weak zeroing reference"什么是“非弱归零参考”
【发布时间】:2015-06-10 23:51:04
【问题描述】:

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

NSNotificationCenter 和 NSDistributedNotificationCenter 不再向可能被释放的已注册观察者发送通知。如果观察者能够存储为调零弱引用,则底层存储将观察者存储为调零弱引用。或者,如果对象不能被弱存储(因为它有一个自定义保留/释放机制会阻止运行时能够弱存储对象)对象被存储为非弱归零引用。这意味着观察者不需要在他们的释放方法中取消注册。 [强调我的]

这对我来说没有意义。如果它是一个非弱引用,那么它不是一个强引用吗?所以 NSNotificationCenter 仍然是所有者,所以对象不会释放(直到手动取消注册),所以在这种情况下说它是“归零”是荒谬的。

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

【问题讨论】:

    标签: objective-c cocoa memory-management nsnotificationcenter osx-elcapitan


    【解决方案1】:

    这个问题的答案在于 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。

    【讨论】:

    • 对于我所指的那种 swizzling 的示例实现,请查看MAZeroingWeakRef
    • 大量详尽的答案,正是我所希望的那种解释。谢谢!
    【解决方案2】:

    将属性声明为强属性会使该属性成为强引用。 将其声明为弱使用归零弱引用。这 unsafe_unretained 修饰符使用非归零弱引用

    简单地说:non-weak zeroing reference == unsafe_unretained refernce

    参考:

    https://mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html http://www.jessesquires.com/UIKit-changes-in-iOS-9/

    【讨论】:

    • 这个问题与更常见的情况不同。不是“什么是非归零弱参考”。这里的问题是“什么是非弱归零参考”。
    • 你的意思是他们是不同的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    相关资源
    最近更新 更多