16

I usually use NSNotification like the sample below:

In viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bar:) name:kName2 object:nil];

In viewDidUnload and dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self];

But a friend told me that I should not use [[NSNotificationCenter defaultCenter] removeObserver:self]; because it will remove all the observers including the super class's . He suggested me to use the following code to remove observer one by one.

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName2 object:nil];

I've checked the ASIHttpRequest library's code ( https://github.com/pokeb/asi-http-request ). It follows my friends' suggestion.

I want to know if my friend is right or not? In my opinion, since the current instance will be unload or dealloc, the super class's notification is also useless. And is there any system UIViewController subclass use notification?

tangqiaoboy
  • 1,476
  • 1
  • 15
  • 32
  • What does it mean it will remove the "super class' observer"? An observer is an object instance not a class. If it is going to be deallocated it _must_ unregister itself from all notifications, even if they were registered in the super class' code. – MrTJ Apr 06 '12 at 08:29
  • @MrTJ I mean the notification observer which is added in super's method. Maybe the class instance's father also need observe some notifications when child's viewDidUnload method is called. – tangqiaoboy Apr 06 '12 at 11:26
  • Might be, might be. If you want to unregister in viewDidUnload then for security also I suggest to use the second method (per observer unregistration) – MrTJ Apr 06 '12 at 12:17

4 Answers4

12

Your friend is 100% correct. Though, it does not matter if you remove all notification observations in dealloc.
You mentioned viewDidUnload, and there the case is completely different, because the unloaded object will stay alive, and you don't know when the notification observations of the superclass are added again. If they are added in viewDidLoad you won't have a problem. If they are added in an init method you just lost a bunch of important notification observations.

Removing observations with specific names is good practice and should be done from the beginning.

Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • Thank you. So we can use `[[NSNotificationCenter defaultCenter] removeObserver:self];` in `dealloc` method, but NOT in `viewDidUnload` method, right? – tangqiaoboy Apr 06 '12 at 11:29
  • Yes, `removeObserver:` shouldn't be used outside of dealloc. But I like to remove each observation specifically myself, so I don't use `removeObserver:` at all. I use the specific method `removeObserver:name:object:` for all my notifications. I like to keep my code very specific. – Matthias Bauch Apr 06 '12 at 13:17
8

When you want to remove all notification you use,

[[NSNotificationCenter defaultCenter] removeObserver:self];

If you want to remove a particular notification you use,

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];

When you no longer in need of any notification the first approach is simple.

Vignesh
  • 10,205
  • 2
  • 35
  • 73
1

As the object is going away, it's safe to use [[NSNotificationCenter defaultCenter] removeObserver:self]; in the dealloc method.

In ViewDidUnload method, you'd better remove each observer one by one as a reference to the controller is still around (and your corresponding viewDidLoad should add them all back in).

Scott Corscadden
  • 2,831
  • 1
  • 25
  • 43
Tang Qiao
  • 21
  • 2
0

I use the first way, I never thought about whether it was right or not. If dealloc is being called, then the object (super as well) is going to be deallocated anyway. What you definitely DON'T want is the NSNotification being sent to a deallocated instance.

borrrden
  • 33,256
  • 8
  • 74
  • 109