In my application I have an object that encapsulates communication to the server through HTTP. This object make some HTTP requests to "poll" if there are changes on the server, such as session is no longer valid, or there are new messages for the user, and so on.
UI objects of the application must register itself to the communication object to receive notifications through a protocol that UI object implements. Registration is done with a method like:
[communicationObject addObserver: self];
and to remove itself:
[communicationObject removeObserver: self];
The communication object store observers in a mutable array. In some cases, UI objects are UIViewControllers that was pushed in a UINavigationController. In that case, when the user back to the parent controller, the UI controller is not disposed, because the observer array of the communication object retain it, and the UI controller can't remove itself from the observer because the dealloc method is never called (obviously).
The question: this observer-notifier is a bad design pattern? There is a way to detect that the UI controller was released by the parent controller without using the viewWillDisappear method? There are best practice to address this type of situations?
If you are using the observer pattern, and you want a view controller to observe a value only while it on the screen, it is a good idea to call addObserver:
in viewDidAppear
, and removeObserver:
in viewWillDisappear
. This is not bad design or misuse of these methods; actually, this is standard practice and a very good use of these view controller methods.
If you want a view controller to continue observing a value even after it gets removed from the screen, first be sure this is really what you want. If it is, there are a few things to remember:
setup
method, and make sure it is called both on instantiation and presentation alike.setup
method being called when a view controller is presented, rather than maintaining a consistent state for the life of the object.nil
. A good way to check whether its view hierarchy is ready is via the isViewLoaded
property.It is important here not to confuse the ideas of a view controller (or any object, for that matter) being retained somewhere, and it being on screen. These are very different events, and often do not coincide. For example, if you have a 'parent' view controller (such as an UINavigationController
) managing one or more 'child' view controllers, there may be multiple view controllers instantiated and retained at one time, while only a single one is presented on screen at a time.
NSNotificationCenter
If you prefer, another option for handling global events is via NSNotificationCenter
, which lets you specify a selector
to call on observers, lets notifications be posted anonymously, and lets arbitrary event objects (userInfo
) be associated with notification events. In this way, your communicationObject
would post notifications to [NSNotificationCenter defaultCenter]
, and your view controllers would observe notifications on the defaultCenter
. You would still add/remove observer objects in a similar way, but you get a centralized, more robust way of coordinating global events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With