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:];
Related
In my code i have a lot of NSNotification around 200+ .
[[NSNotificationCenter defaultCenter] addObserver....];
[[NSNotificationCenter defaultCenter] postNotificationName...];
Will this impact on my application performance if I register and fire notification a lot?
This is depend on how to handle NSNotificationCenter in your code.if you handle your NSNotification purely then its effect bcoz its called twice or more times..
best approach for NSNotification is you add in your viewWillAppear and remove it on viewWillDisappear.
Instead of NSNotificationCenter you should have a look at tolo
The biggest advantage is that you don't have to care about adding/removing observers - tolo does this for you automagically.
ps. failing to remove any observer might lead to retain cycles and memory leaks
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
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.
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.
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.