I currently make use of this method in my objective-C app:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleEnteredForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
If I don't remove it with
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
am I at risk of a memory leak? Or is there a good way to utilize this notification without the risk of a memory leak?
There is no danger of a memory leak; the notification center's reference to your observer self is weak.
But there is a danger — namely, that self will go out of existence and that the notification center will later attempt to send it a notification. This will cause a horrific crash, one that is very difficult to track down (dangling pointer).
That is why you must be certain to unregister your observer in iOS 8 and before.
Starting in iOS 9, however, this ceases to be a problem, because the notification center's reference to your observer is not simply weak but is ARC-weak. This means that the reference to a released observer becomes nil. The notification center detects this and stops sending notifications to it, safely.
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
I have a cordova plugin that depends on a an accessory being connected to my iOS device. The accessory (a magnetic swiper) on notification that something is being swiped. However I not sure what I should be setting the observer as. In the example code they provide it they set it as self but that in a ViewController My plug in is not in the app controller. Any ideas?
this is the notification code that the sample code had( again this was in the ViewController:
[[NSNotificationCenter defaultCenter] addObserver: self
selector:#selector(trackDataReady:)
name: #"trackDataReadyNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(devConnStatusChange)
name:#"devConnectionNotification"
object:nil];
As long as the object (self) is still allocated it will receive the messages when they are posted to the NSNotificationCenter defaultCenter. It does not have to be a view controller. Remember though when the object is deallocated removed the observers otherwise you will get application crashes.
Am using NSNotificationCenter in my iPhone App to post a notification
// I add an observer in didFinishLanchingWithOptions() in the AppDelegate
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(getData:) name:kNotif_GetData object:nil];
....
....
// then in another method, I post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:kNotif_GetData object:nil];
....
One user says that this functionality (which is executed by getData()) is not working. so that might mean that the notification hasn't gotten fired. Any idea why this might happen? When I test it with different devices, it works perfect. The user uses iPhone5 and iOS7. Is there any more setting or any explicit user setting which is needed or which could turn this on/off?
No, notification centre is reliable.
"Not working" is not enough information to diagnose the problem. Get more information from the user or add more logging so that you know what is actually going on.
I am implementing facebook's SDK for iOS into my app. There are two functions however that are supposed to register and unregister for the notifications:
From Facebook's login to facebook with ios:
in the viewDidLoad method, register for the session change notification you defined in the app delegate by adding this code to the end of the method:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
and
Unregister for the notifications by adding the following code to the end of the didReceiveMemoryWarning the method:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Since I have quite a few view controllers and all of them should be using facebook's API, I thought I should implement the register/unregister methods in the applicationDidFinishLoadingWithOptions (for register for notifications)
but I am not sure if and how I should implement the unregister's removeObserver command, because applicationDidReceiveMemoryWarning is not available for the AppDelegate.
Is DidReceiveMemoryWarning visiting all the viewControllers of the App?
Would it be sufficient to unregister in just one of my viewControllers ?
The application delegate does receive memory warnings:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html
If it didn't, another option would be to use the notification center:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:#selector(whatever:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
That all said, it seems to me that removing the observer on a memory warning is inappropriate. At what point will your reinstate it? But hey, if that's what Facebook recommends...
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.