避免保留循环,NSNotificationCenter?
Avoid Retain Cycles, NSNotificationCenter?
此类别方法是否允许我避免对 NSNotificationCenter
观察者的额外保留?
#import "NSNotificationCenter+Util.h"
@implementation NSNotificationCenter (Util)
- (void)addWeakObserver:(nonnull NSObject*)observer selector:(nonnull SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject {
__weak NSObject *weakObserver = observer;
[self addObserver:weakObserver selector:aSelector name:aName object:anObject];
}
@end
目标是让对象消亡而不必将其移除。
注意:我正在努力避免这种情况导致保留周期:
Be sure to invoke removeObserver:name:object:
before
notificationObserver
or any object specified in
addObserver:selector:name:object:
is deallocated.
否 — weakObserver
将是 weak
,因此如果 observer
被释放,将自动 nil
,但如果 addObserver:...
保留观察者,则它保留观察者。对象中没有关于先前引用持有它的方式的历史记录,是引用本身控制它们自己的行为。
然而,NSNotificationCenter
不保留其观察者,而观察者几乎从不保留通知中心。没有保留周期。您引用的文本或多或少是这样说的:存储在通知中心内的指针将变得悬空,即它不主张所有权。
您所做的也不会使引用自动存储在中心内nil
。
从 iOS 9 和 OS X v10.11 开始,此行为 is already fixed。通知中心对所有可以弱引用的对象都使用弱引用。
NSNotificationCenter
不保留 observer
,因此您不会仅使用 addObserver:selector:name:object:
创建循环保留。你不需要包装方法。
关于调用 removeObserver:name:object:
的警告的原因是因为 NSNotificationCenter
直到 OS X 10.11 (El Capitan) 和 iOS 9 才使用归零弱引用. 在这些版本之前的操作系统中,如果您在 observer
被释放时未能从通知中心删除 observer
,则通知中心将继续尝试向 observer
发送通知。这通常会导致崩溃或更糟。
如果您的部署目标至少是 OS X 10.11 或 iOS 9,那么您不必担心在解除分配时删除 observer
。
请注意,如果您使用 -[NSNotificationCenter -addObserverForName:object:queue:usingBlock:]
,那么我相信您确实需要担心避免由强烈保留您的观察者的块引起的保留循环。
此类别方法是否允许我避免对 NSNotificationCenter
观察者的额外保留?
#import "NSNotificationCenter+Util.h"
@implementation NSNotificationCenter (Util)
- (void)addWeakObserver:(nonnull NSObject*)observer selector:(nonnull SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject {
__weak NSObject *weakObserver = observer;
[self addObserver:weakObserver selector:aSelector name:aName object:anObject];
}
@end
目标是让对象消亡而不必将其移除。
注意:我正在努力避免这种情况导致保留周期:
Be sure to invoke
removeObserver:name:object:
beforenotificationObserver
or any object specified inaddObserver:selector:name:object:
is deallocated.
否 — weakObserver
将是 weak
,因此如果 observer
被释放,将自动 nil
,但如果 addObserver:...
保留观察者,则它保留观察者。对象中没有关于先前引用持有它的方式的历史记录,是引用本身控制它们自己的行为。
然而,NSNotificationCenter
不保留其观察者,而观察者几乎从不保留通知中心。没有保留周期。您引用的文本或多或少是这样说的:存储在通知中心内的指针将变得悬空,即它不主张所有权。
您所做的也不会使引用自动存储在中心内nil
。
从 iOS 9 和 OS X v10.11 开始,此行为 is already fixed。通知中心对所有可以弱引用的对象都使用弱引用。
NSNotificationCenter
不保留 observer
,因此您不会仅使用 addObserver:selector:name:object:
创建循环保留。你不需要包装方法。
关于调用 removeObserver:name:object:
的警告的原因是因为 NSNotificationCenter
直到 OS X 10.11 (El Capitan) 和 iOS 9 才使用归零弱引用. 在这些版本之前的操作系统中,如果您在 observer
被释放时未能从通知中心删除 observer
,则通知中心将继续尝试向 observer
发送通知。这通常会导致崩溃或更糟。
如果您的部署目标至少是 OS X 10.11 或 iOS 9,那么您不必担心在解除分配时删除 observer
。
请注意,如果您使用 -[NSNotificationCenter -addObserverForName:object:queue:usingBlock:]
,那么我相信您确实需要担心避免由强烈保留您的观察者的块引起的保留循环。