0

As of iOS 6.0 , viewDidUnload method is deprecated. Before iOS 6 I used to removeObserver of NSNotification in viewDidUnload method. But since it is deprecated , I have moved it to didReceiveMemoryWarning. Now if my app receives the low memory waring , notification are removed. So my code written in NSNotification doesn't work.

Can anybody tell me how can I solve this issue ?

Thanks in advance.

iOSAppDev
  • 2,755
  • 4
  • 39
  • 77

2 Answers2

4

I assume that you added the observer in viewDidLoad. The problem is that on iOS 6 views are not unloaded, even in a low memory situation. Therefore, if you remove the observer in didReceiveMemoryWarning, viewDidLoad will not be called again.

There are two relative simple alternatives that you can choose from:

  • Add the observer in viewWillAppear and remove it in viewWillDisappear.
  • Add the observer in your initXXX method and remove it in dealloc.

I is possible to add the observer in viewDidLoad and remove it in didReceiveMemoryWarning. But then you have to "manually unload" the view in didReceiveMemoryWarning, so that viewDidLoad is later called again. See e.g. https://stackoverflow.com/a/15805715/1187415 for sample code how to forcibly unload the view.

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks for reply. I can follow first alternative as I need notifications while app is running.Can I add observer in viewDidLoad & remove it in dealloc method ? Thanks – iOSAppDev Apr 20 '13 at 10:12
  • @iOSAppDev: Yes, but you have to set a flag whether the observer was added or not, because 1) dealloc might be called without viewDidLoad being called before, 2) if you later rewrite your code to forcibly unload the view, viewDidLoad would be called again. But the number of addObserver/removeObserver calls must match exactly. – Martin R Apr 20 '13 at 10:16
  • What I understand from your comment is I need to add one flag lets say isObserverRemovedForNotification. I will set this in dealloc. So in viewDidLoad , I will check `if(isObserverRemovedForNotification) { // Add observer for notification }` Is it correct ? Also Can I write dealloc method with ARC ? – iOSAppDev Apr 20 '13 at 12:21
  • @iOSAppDev: You should not add the observer twice, but I would go the other way around: `if (!isObserverAdded) { isObserverAdded = YES; ... add observer }`. But what newacct has said in his answer is also valid: You can add the observer in viewDidLoad and remove it in viewDidUnload + dealloc. - And yes, it is perfectly OK write a dealloc method in ARC. Just don't call `[super dealloc]`. – Martin R Apr 20 '13 at 12:26
  • But in iOS 6 viewDidUnload method is deprecated. So it creates warnings in project. – iOSAppDev Apr 20 '13 at 12:28
  • On iOS 6 (as newacct correctly said) the view will never be unloaded and viewDidUnload never be called (unless you force it as in the link that I gave). So if your deployment target is >= 6.0, you can add the observer in viewDidLoad and remove it in dealloc, viewDidLoad will only be called once. - If you set the deployment target to 5.0, then viewDidUnload might be called and you can use it to remove the observer. - Alternatively, you can use viewWillAppear/viewWillDisappear. – Martin R Apr 20 '13 at 13:16
  • Thanks Martin for your help. I really appreciate it. – iOSAppDev Apr 20 '13 at 13:25
0

The problem is you are completely misunderstanding what viewDidUnload means. viewDidUnload is called when the view is unloaded. In pre-iOS 6, when you are done with a view controller, its view does NOT get unloaded. In pre-iOS 6, 99% of the time you will never see viewDidUnload being run, because views are usually not unloaded. In pre-iOS 6, views are only unloaded in response to a memory warning and the view is not visible. In iOS 6, the only change is that views are never unloaded, even in a memory warning.

The behavior of viewDidUnload is identical in pre-iOS 6 and iOS 6 -- it is called when the view is unloaded. Because of this, you should NOT have to change any code for iOS 6. If you do, you did something wrong.

Before iOS 6 I used to removeObserver of NSNotification in viewDidUnload method.

If what you mean is that you added the observer in viewDidLoad, then you must have it removed in dealloc. Otherwise your code will crash. As I said above, 99% of the time, in pre-iOS 6, views are not unloaded. The typical flow is init -> viewDidLoad -> dealloc. The view does not get unloaded in the middle.

You can optionally also remove the observer in viewDidUnload. It is a good idea because it returns it to the state before the view was loaded. However, it is not strictly necessary, because when the view loads again, viewDidLoad will be called, and overwrite whatever state there was before anyway.

So the answer is, you should not have to change anything in response to iOS 6. Whatever you did in viewDidLoad should be undone in both viewDidUnload (optional) and dealloc (required). This is true in both iOS 6 and pre-iOS 6.

newacct
  • 119,665
  • 29
  • 163
  • 224
  • Thanks for reply . According to your answer I can add observer in viewDidLoad & remove it in dealloc method , right ? Can I write dealloc method with ARC ? – iOSAppDev Apr 20 '13 at 11:09