I have an objective C class. In it, I created a init method and set up a NSNotification in it
//Set up NSNotification
[[NSNotificationCenter defaultCenter] a
If the observer is added to a view controller, I strongly recommend adding it in viewWillAppear
and removing it in viewWillDisappear
.
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
It is important to notice also that viewWillDisappear
is called also when the view controller present a new UIView. This delegate simply indicate that the view controller main view is not visible on the display.
In this case, deallocating the notification in viewWillDisappear
may be inconvenient if we are using the notification to allow the UIview to communicate with the parent view controller.
As a solution I usually remove the observer in one of these two methods:
- (void)viewWillDisappear:(BOOL)animated {
NSLog(@"viewController will disappear");
if ([self isBeingDismissed]) {
NSLog(@"viewController is being dismissed");
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"actionCompleted" object:nil];
}
}
-(void)dealloc {
NSLog(@"viewController is being deallocated");
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"actionCompleted" object:nil];
}
For similar reasons, when I issue the notification the first time, I need to account for the fact that any time a view with appear above the controller then viewWillAppear
method is fired. This will in turn generate multiple copy of the same notification. Since there isn't a way to check if a notification is already active, I obviate the problem by removing the notification before adding it:
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"viewController will appear");
// Add observers
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"imageGenerated" object:nil]; // This is added to avoid duplicate notifications when the view is presented again
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedImageFromCameraOrPhotolibraryMethodOnListener:) name:@"actionCompleted" object:nil];
}
override func viewDidLoad() { //add observer
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector:#selector(Yourclassname.method), name: NSNotification.Name(rawValue: "NotificationIdentifier"), object: nil)
}
override func viewWillDisappear(_ animated: Bool) { //remove observer
super.viewWillDisappear(true)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "NotificationIdentifier"), object: nil)
}
Since iOS 9 it's no longer necessary to remove observers.
In OS X 10.11 and iOS 9.0 NSNotificationCenter and NSDistributedNotificationCenter will no longer send notifications to registered observers that may be deallocated.
https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/index.html#10_11NotificationCenter
*edit: This advice applies to iOS <= 5 (even there you should be adding in viewWillAppear
and removing in viewWillDisappear
- however the advice applies if for some reason you've added the observer in viewDidLoad
)
If you've added the observer in viewDidLoad
you should remove it in both dealloc
and viewDidUnload
. Otherwise you'll end up adding it twice when viewDidLoad
is called after viewDidUnload
(this will happen after a memory warning). This isn't necessary in iOS 6 where viewDidUnload
is deprecated and won't be called (because views are no longer automatically unloaded).