此类别方法是否允许我避免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
目标是让对象死掉而不必将其移除。
注意:我试图避免这种情况导致保留周期:
请务必先调用
removeObserver:name:object:
notificationObserver
或其中指定的任何对象addObserver:selector:name:object:
已取消分配。
答案 0 :(得分:7)
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:]
,那么我相信您必须担心避免因阻止强烈保留观察者而造成的保留周期。
答案 1 :(得分:5)
否 - weakObserver
将为weak
,因此如果nil
被取消分配,则自动observer
,但如果addObserver:...
保留观察者,则会保留观察者。在一个对象中没有关于先前引用的方式的历史,它是控制自己行为的引用本身。
但是,NSNotificationCenter
并未保留其观察员,观察员几乎从不保留通知中心。没有保留周期。您引用的文字或多或少地说明了这一点:存储在通知中心内的指针将变为悬空状态,即它没有声明所有权。
您所做的事情也不会自动nil
将参考文件存储在中心内。
从iOS 9和OS X v10.11开始,此行为is already fixed。通知中心使用弱引用来处理可以被弱引用的所有对象。