NSNotificationCenter in viewDidLoad: not working - iphone

for some reason this code isn't working in viewDidLoad, but will work in viewWillAppear. Any ideas?
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(wakeUp:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
Thank you

you're definitely sure viewDidLoad is being invoked?

For my case is that I put the removeObserver method inside didReceiveMemoryWarning method, and if I take a picture or do something else, this method fires out of my expect. So, now I always remove notification observer at dealloc stage.

Related

NSNotificationCenter one post causes observers to be called twice

I have the following code:
[[NSNotificationCenter defaultCenter] postNotificationName:kNewsfeedFetchCompleted object:self userInfo:userinfo];
only this, no where else. And here's how I set the observer:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(newsfeedFetchCompleted:) name:kNewsfeedFetchCompleted object:nil];
question is when I do one post the newsfeedFetchCompleted is called twice.. how is this even possible?
This is possible when your code for addObserver is executed twice. The notification function will be called as many times as it is registered.
So make sure your code for adding observer is executed for once only. So, you can keep it in viewDidLoad or init method.
If you are putting it in viewWillAppear then remove observer in viewWillDisAppear.
before you add observer, make sure you remove the previous observer added.
[[NSNotificationCenter defaultCenter]removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(newsfeedFetchCompleted:) name:kNewsfeedFetchCompleted object:nil];
It is possible if you have added the same observer multiple times for the newsfeedFetchCompleted notification. You should match your addObserver calls with removeObserver calls.
For example if you added the observer in viewWillAppear/viewWillDidAppear/ViewDidLoad of a UIViewController, you should remove it in viewWillDisappear/viewDidDisappear/ViewDidUnload.
The corresponding remove call for addObserver, is removeObserver:name:object:
More info can be found in the NSNotificationCenter docs

is removeObserver necessary on dealloc?

In one of my view controller, it adds itself as observer of UITextViewTextDidEndEditingNotification notification, like the following does
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(done:) name:UITextViewTextDidEndEditingNotification object:nil];
Now I am wondering - do I need to do the following when the view controller is dealloc'd
[[NSNotificationCenter defaultCenter] removeObserver:self];
yes, you should always remove any observers when they're being dealloc'd. otherwise the notification center will keep references to the now-dealloc'd objects around and continue to try to forward notifications to them.

Where should I remove a notification observer?

I set up a notification observer in my view controller's init method like so:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(saveState)
name:UIApplicationWillResignActiveNotification
object:nil];
Where is the best place to call removeObserver:name:object: for this notification. I'm currently calling it in my dealloc method, but wanted to know if that might cause problems.
No, you got it right. dealloc is the correct location to remove notification observers (unless you have some specific reason to need to remove the observer earlier).
You can always remove the observer in viewWillDisappear:, or when you are done using it and have no other need for it, you can place it in a function.
If the -saveState only need to execute once when active, then you can removeObserver inside the -saveState.

addobserver / removeobserver query

Is it OK to use -removeObserver: first and then call -addObserver: with the same name? Or is it a rule to have -addObserver: first before -removeObserver:?
I tried it using OS 4.0 and it seems OK (no crash, warnings... etc.).
-(void) setObserver
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:OBSERVER_NAME object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector: #selector(selectorName)
name:OBSERVER_NAME
object:nil];
}
The reason is to prevent two observers with the same selectorName method being called twice assuming that -setObserver method was called again if its inside -viewDidLoad and a memory warning was issued.
Also, do I need to invoke -removeObserver: during -dealloc?
If you're getting -selectorName invoked twice, there's probably some other issue with your code. And even if Cocoa will be graceful about removing observers you haven't added yet, I wouldn't actually do that.
As user tonklon says in a comment, you should probably remove the observer in -viewDidUnload. As to your last question, it's also reasonable to remove the observer in -dealloc, though it's good practice to structure your code such that things like removing observers happen at a deterministic time rather than as a side-effect of memory management.

Determine if UIViewController is closing due to application exit?

Is there a way to test in viewWillDisappear if it's being called because the application is exiting, versus normal ways of it being dismissed? The method applicationWillTerminate in the App Delegate is called after the current view is closed. I want to do different things depending on whether it's being dismissed due to a IBAction or the user clicking the menu button.
Thanks!
You should use observe the UIApplicationWillTerminateNotification in your controller, set a flag, and then check for the flag in your viewWillDisappear implementation.
NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self
selector:#selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:nil];
I haven't used it for your purposes yet, but the UIApplicationWillResignActiveNotification notification might occur before applicationWillTerminate is called.
Just throw...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillResign:) name:UIApplicationWillResignActiveNotification object:NULL];
... into your UIViewController to test it out.