What happens when a nsnotification is sent to an inactive viewcontroller? - objective-c

In my applicationWillEnterForeground, I check and send a notification if data refresh is necessary:
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshModelNotification" object:nil];
The only observer for that particular notification is a particular view controller:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(refreshData:) name:#"refreshModelNotification" object:nil];
That view controller is one of several inside a UITabBarController.
My question is: what happens if that view controller isn't the active tab when the notification is sent?
Thanks in advance.

If the observer is still set for the view controller the view controller will still receive the notification and behave normally except any visual changes to the view controller's view will not be seen

Related

A dismissed presented view controller keeps responding to NSNotification

I have a view controller that is modally presented, and I add it as an observer for a notification. After I dismiss the view controller, it keeps responding to the notification. Is this normal? If so, what should be done?
You should unregister the view controller from notification centre.
The good way to do that is do the register to notification in viewDidAppear method and unregister in viewDidDisappear.
Seems like you forget to remove observer after dismissing and your view controller is retained somewhere:
- (void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

Send notification to another view controller when request finishes

I am working on an Iphone Application (ios5 + storyboard + arc).
I have 2 ViewControllers A and B.
In A I have a button. when pressed I am submitting a request asynchronously to the server (using AFNetworking) and I will go to View Controller B by using performSegueWithIdentifier (push not modal).
When the request finishes it executes a request successful Block that will save data to the database. (The block is in ViewController A since the request is sent from there)
Is there a way I can notify ViewController B that the request has finished and execute a method in B?
What I'm looking for is that when the request finishes and enters the Success Block I run a method in view controller B which is the loaded view.
I hope I was clear.
Thanks
For posting a notification use the below code:
[[NSNotificationCenter defaultCenter] postNotificationName:#"Midhun" object:nil];
In the viewDidLoad of the notification listening class add observer like:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(performTask:) name:#"Midhun" object:nil];
performTask: is the method which will be called when the notification is observed.
Please refer NSNotification Class Reference
First options is to store reference to view controller B somewhere (as example in application delegate) and use it to run a method.
The second one is to send notification via [NSNotificationCenter defaultCenter], so controller B set a listener to a notification somewhere (viewDidLoad can be a good place):
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(finished:) name:#"requestfinishes" object:nil];
and controlle A sends it:
[[NSNotificationCenter defaultCenter] postNotificationName:#"requestfinishes" object:nil userInfo:nil];
Note that if you send a notification from a different thread, listener will be executed on the same thread.

Looking for some sort of TableViewDidDisplayNotification

I have a split view based app, and would like to listen for some sort of notification for when the root menu is displayed. The reason I want to do this is because the keyboard overlaps the menu, so I would like to hide the keyboard when the menu is displayed.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:<Some Notification Here>
object:self.view.window];
I already have the method to hide the keyboard, I'm just looking for the appropriate notification.
Thanks!
you can post the notification yourself from the root menu. Just subclass it and post the notification on viewDidAppear or viewWillAppear.
The word of warning: if you are targeting iOS 5 and up you should kep in mind the viewWillAppear and viewDidAppear are deprecated in iOS6. use
willMoveToParentViewController or didMoveToParentViewController or -(void)viewWillLayoutSubviews
-(void)willMoveToParentViewController:(UIViewController *)parent{
if (!parent)
//post notification here
}
Also, you can provide nil as a notification name and listen to any possible notification, then NSLog it out, perhaps you can find a useful notification there, just make sure it is documented to futureproof your product.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationReceived:) name:nil object:nil];

nsnotification for specific object

Im working on an ios app, ios 5+ , using xcode and objective c. Ok currently messing with nsnotifications and i just need some clarifications as im a wee bit confused.
Lets say i have a view controller that i add an observer to like so
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showContent:) name:kTPSShowContentNotification object:self];
where the object is set to self. I took this to mean that it is only looking from that notification if sent from that object. am i wrong on that?
elsewhere in code I am positing a notification like so
[[NSNotificationCenter defaultCenter] postNotificationName:kTPSShowContentNotification object:currentVC];
where currentVC is the view controller that has the observer set up initially.
I thought this is all that was needed to catch that notification as the post is telling the notification center to send it from that view controller. but it fails to catch it and im unsure as to why. If when adding the observer i set the object as nil then it catches it but so does all the other viewcontrollers (if any ) that have observers for that notification too. Is there any way around this ? am i approaching this completely wrong?
To receive notification only from theObjectSendingNotification object you should write:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showContent:) name:kTPSShowContentNotification object:theObjectSendingNotification];
and the object sending notification should send it in this way
[[NSNotificationCenter defaultCenter] postNotificationName:kTPSShowContentNotification object:self];
If I'm getting this right, you want to post and get a notification from the same controller. So you can do something like this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showContent:) name:kTPSShowContentNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:kTPSShowContentNotification object:self];
But it should work indeed if your currentVC ivar is pointing to the very same controller. The fact that you say it doesn't work makes me believe that it is not pointing to the same instance of your controller.

reloadData in MasterView from DetailView

I ran into an issue similar to this earlier on the iPhone, but the same solution doesn't seem to apply to the iPad environment. My goal is to call my method forceReload, defined in my RootViewController, that will reload the countdown_table's data in the RootView from the DetailView once a modal is dismissed. forceReload works fine when called directly from the RootViewController, but I can't seem to point to point to the RootViewController from the DetailView.
I've tried using
RootViewController *root_view = [self.splitViewController.viewControllers objectAtIndex:0];
[root_view forceReload];
[root_view.countdown_table reloadData];
But that only points to the Navigation Controller, not the View Controller inside of it. Even when the modal is dismissed, RootViewController's viewWillAppear does not fire.
How can I point to this file?
Thanks!
Try using notifications, i.e., register RootViewController as an observer for notifications that your DetailView or any view may send.
in RootViewController's viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(forceReload)
name:#"reloadRequest"
object:nil];
viewDidUnload or in dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self];
And in your DetailViewController or your modal view (you didn't say they're the same), put this right before you dismiss the view or exactly when you need RootViewController to call forceReload:
NSNotification *notif = [NSNotification notificationWithName:#"reloadRequest" object:self];
[[NSNotificationCenter defaultCenter] postNotification:notif];