什么是 "non-weak zeroing reference"
What is a "non-weak zeroing reference"
在 OS X v10.11 beta release notes 中,我找到以下内容:
NSNotificationCenter and NSDistributedNotificationCenter no longer send notifications to registered observers that may be deallocated. If the observer is able to be stored as a zeroing-weak reference the underlying storage stores the observer as a zeroing weak reference. Alternatively, if the object cannot be stored weakly (because it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) the object is stored as a non-weak zeroing reference. This means that observers are not required to un-register in their deallocation method. [emphasis mine]
这对我来说没有意义。如果是非弱引用,那岂不是强引用?所以 NSNotificationCenter 仍然是所有者,所以对象不会解除分配(直到手动取消注册),所以在这种情况下说它是 "zeroing".
是荒谬的
如果这是指某种 __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
)来禁用对您的对象的弱引用,在这种情况下,它很可能会通过 swizzling -dealloc
在对象上。当然,这是所有的实现细节,所以 NSNotificationCenter 可以有它自己创新的做事方式,但这是我最好的猜测,没有尝试反汇编 NSNotificationCenter。
Declaring a property as strong makes that property a strong reference.
Declaring it as weak uses a zeroing weak reference. The
unsafe_unretained modifier uses a non-zeroing weak reference
简述: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/
在 OS X v10.11 beta release notes 中,我找到以下内容:
NSNotificationCenter and NSDistributedNotificationCenter no longer send notifications to registered observers that may be deallocated. If the observer is able to be stored as a zeroing-weak reference the underlying storage stores the observer as a zeroing weak reference. Alternatively, if the object cannot be stored weakly (because it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) the object is stored as a non-weak zeroing reference. This means that observers are not required to un-register in their deallocation method. [emphasis mine]
这对我来说没有意义。如果是非弱引用,那岂不是强引用?所以 NSNotificationCenter 仍然是所有者,所以对象不会解除分配(直到手动取消注册),所以在这种情况下说它是 "zeroing".
是荒谬的如果这是指某种 __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
)来禁用对您的对象的弱引用,在这种情况下,它很可能会通过 swizzling -dealloc
在对象上。当然,这是所有的实现细节,所以 NSNotificationCenter 可以有它自己创新的做事方式,但这是我最好的猜测,没有尝试反汇编 NSNotificationCenter。
Declaring a property as strong makes that property a strong reference. Declaring it as weak uses a zeroing weak reference. The unsafe_unretained modifier uses a non-zeroing weak reference
简述: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/