Will this category method allow me to avoid additional retains on NSNotificationCenter
observers?
#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
The goal is to have the object die without having to remove it.
Note: I'm trying to avoid this causing retain cycles:
Be sure to invoke
removeObserver:name:object:
beforenotificationObserver
or any object specified inaddObserver:selector:name:object:
is deallocated.
No —
weakObserver
will beweak
, so will automaticallynil
ifobserver
is deallocated, but ifaddObserver:...
retains the observer then it retains the observer. There's no history in an object as to the ways that previous references have held it, it's the references themselves that control their own behaviour.However,
NSNotificationCenter
doesn't retain its observers, and observers almost never retain the notification centre. There is no retain cycle. The text you've quoted more or less says this: that pointers stored within the notification centre will become dangling, i.e. it is not asserting ownership.What you've done also won't make the references stored within the centre automatically
nil
.As of iOS 9 and OS X v10.11, this behaviour is already fixed. A weak reference is used by the notification centre for all objects that can be referenced weakly.
NSNotificationCenter
doesn't retainobserver
, so you won't create a retain cycle just usingaddObserver:selector:name:object:
. You don't need a wrapper method for that.The reason for the warning about calling
removeObserver:name:object:
is becauseNSNotificationCenter
didn't use zeroing weak references until OS X 10.11 (El Capitan) and iOS 9. In operating systems prior to these versions, if you fail to removeobserver
from the notification center whenobserver
is deallocated, then the notification center will continue trying to send notifications toobserver
. This will generally cause a crash or worse.If your deployment target is at least OS X 10.11 or iOS 9, then you don't have to worry about removing
observer
when it is deallocated.Note that if you use
-[NSNotificationCenter -addObserverForName:object:queue:usingBlock:]
, then I believe you do have to worry about avoiding a retain cycle caused by the block strongly retaining your observer.