在OS X v10.11 beta release notes中,我找到以下内容:
NSNotificationCenter和NSDistributedNotificationCenter不再向可能已解除分配的已注册观察者发送通知。如果观察者能够存储为归零弱引用,则底层存储将观察者存储为归零弱引用。或者,如果对象无法以弱方式存储(因为它具有自定义保留/释放机制,可防止运行时能够弱存储对象)该对象存储为非弱的归零引用。这意味着观察者不需要在他们的释放方法中取消注册。 [强调我的]
这对我没有意义。如果它是一个非弱参考,那么它不是一个强大的参考吗?因此,NSNotificationCenter仍然是所有者,因此该对象不会解除分配(直到手动取消注册),因此在此上下文中说它是“归零”是没有意义的。
如果这是指某种__unsafe_unretained
引用,那么问题是...... NSNotificationCenter如何避免发送僵尸消息?
答案 0 :(得分:4)
这个问题的答案在于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
)来禁用对对象的弱引用,在这种情况下,它很可能被调用{{1}在对象上。当然,这是所有实施细节,因此NSNotificationCenter可以拥有自己创新的做事方式,但这是我最好的猜测而不试图拆解NSNotificationCenter。
答案 1 :(得分:-1)
将属性声明为强大使该属性成为强引用。 将其声明为弱使用归零弱引用。该 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/