NSNotificationCenter change observers order [duplicate] - ios

This question already has answers here:
NSNotification order of observer notifications
(3 answers)
Closed 9 years ago.
I have list of objects in my iOS application, which observe some changes using NSNotificationCenter.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onSomeChanges)
name:#"SomeConstantNotificatioName" object:nil];
So when notification is posted, NSNotificationCenter calls onSomeChanges methods in the same order as addObserver methods were called.
The question is there any way to changed this order?
What I need is ability to call some adding observer method, which will insert needed observer as the first element of the observers list. So no matter in what order observers are added, some object will receive notification first.
Thank you

You can't change order of observers, even if you add them in order you want there is no guaranty that notification center calls them in right order. I suggest you to add one observer that require to be called first and then post another notification for others. This will be hard to debug later but you will be sure about order in this case

Related

NSNotificationCenter - Observer selectors not being called

I've gone from having all my observers selectors of multiple NSNotifications being called to none of them working. Is there an XCode/Application setting that I may have disabled that could cause this behaviour?
This issue affects just about every class that I have registered as an observer. Everything was working fine a few days ago. I'm setting the observers mainly in viewDidLoad and removing them in dealloc.
Just to add: All notifications are being posted as I have already tested for this.
I ended up figuring it out. I can't believe I missed this.
The common super class for all observers was removing itself as an observer for all notifications in viewDidDisappear.
I have now changed this to only remove itself as an observer for a specific NSNotification using [[NSNotificationCenter defaultCenter] removeObserver:name:object:];

Settings Changed Notification In Subclass Of IASKAppSettingsViewController

I have a subclass of IASKAppSettingsViewController that I, of course, use to display and handle various events for the settings I present to the user.
In this subclass, I am trying to receive the notification that settings were changed by adding this line to -(void)viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(settingsChanged:) name:kIASKAppSettingChanged object:nil];
Problem is that the method, settingsChanged, is never being called. I figure that there is some other way of doing this or I am doing something wrong here. This procedure does work for me in other classes, so I assume there is something special about IASKAppSettingsViewController that is preventing this from working. Can someone point me in the right direction?
EDIT #1
Received a message from Future Tap via GitHub and he asked me to check the sample app. I did and the sample app does not use a subclass of IASKAppSettingsViewController. I have since added another addObserver and that is also not being called. I verified that both addObserver calls are being executed, so that is not the cause.
EDIT #2
It appears that something is terribly amiss in my app. I have multiple classes that observe this notification and they all use the same name for the method to be called (settingsChanged). When I Command-click the name of the method in one addObserver call, Xcode brings me to another class' settingsChanged method. This is probably what is causing some of my observer methods not to get called.
Working with Future Tap, we discovered that `IASKAppSettingsViewController' was removing all observers when the view disappeared. This was causing the observers that I set up to be removed and, thus, not be called. The code has been fixed and my problem is solved.

Is there a way to check if observer listens to some NSNotification?

I want to check if my view is listening for UIApplicationWillResignActiveNotification or not. If it is listening then I want to remove it during dealloc. Now I was wondering if there is way to do this using objective c ?
I am not trying avoid multiple additions for notifications. Here is bit more explanation of what I am trying to do.
I have custom gridView. I can initialize it with either scaling enabled or scaling disabled. If init with scaling enabled I add itself as observer of UIApplicationWillResignActiveNotification but if its init with scaling disabled then it does not add itself as an observer for that notification. Now, in dealloc I want to remove that gridView as an observer of that notification. So I was wondering if there is way to find out if gridView is listening to that notification or not.
I don't know of any way to check what notifications your observer is listening for, but regardless of whether it's listening for UIApplicationWillResignActiveNotification or not, calling:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification];
will cause self to stop listening for that notification, or do nothing if self is not listening for it.
Specifying the name of the notification you want to stop listening for is the best practice, but since you said you're putting this in dealloc, it would also be safe to just do this:
[[NSNotificationCenter defaultCenter] removeObserver:someObserver];
If you want to check in dealloc method, if your view is registered as observer to correctly remove it - you should not. All you need to do is:
[[NSNotificationCenter defaultCenter] removeObserver:myView]
and it will remove observers for all notifications you subscribed
NSNotificationCenter does not support this out-of-the-box. You have the same problem with KVO.
Generally one just keeps track of whether or not an object has been registered using a boolean property and unregisters only if this boolean has been set.

Refreshing Parse.com data when the app becomes active

[Edited with solution below]
I want to call a Parse.com query whenever the app becomes active, so that if it's brought up from the foreground, a new set a data will be called.
I realize there is a method for this in the AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
But I want to know how I can put the query information obtained in my AppDelegate and put it in my ViewController where I can display the information.
Any ideas on what I might do? Or if there is another way to make the query when the app becomes active? Thanks.
So here is what I came up with. I had my method (called getData) in the ViewController, and in the viewDidLoad method, I inserted this code
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(getData)
name:UIApplicationDidBecomeActiveNotification object:nil];
And now it works just as I had hoped. Thanks!
This is a really broad question, but what you can do is you can post a notification and make your view controller listen to it.
Then after your app re enter from background, you can post the notification and in the observer method that you implemented in the view controller, you can pull the data from Parse.
See this question to understand the sequence of the method calls.

If add an observer for a notification in the AppDelegate, do I need to bother removing it?

In the AppDelegate's didFinishLaunchingWithOptions:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(contextChanged:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
This is so I can merge changes to the data from other threads.
Question: Do I need to bother removing this listener in applicationWillResignActive or applicationWillTerminate? It doesn't seem like there's a point. I guess I'm asking if it's normal to have listeners like this in the main loop that never get removed.
You can never remove it, but if your app receive a notification (it won't happen in this case) while it is in background the notification will be queued and delivered to the application when it comes up again (if the app isn't killed ofc).
If don't want notifications that happen when your app is in background to be delivered once it comes up you can remove the listener in the methods you pointed out.
In this case, actually, it doesn't matter.

Resources