3

NB: I saw a few questions being asked in this front, but none seem to have clarified my doubt.

Pre iOS6, all outlets, heavy resources like images and sounds were set to nil in viewDidUnload. Post iOS6, this is no more the case as views are not unloaded anymore. The system calls didReceiveMemoryWarning and this is the new recommended place to put such resource neutralizations.

So what if the code needs to support everything above iOS4? On devices running iOS 4 and 5, viewDidUnload will still be getting called. And in devices running iOS6, only didReceiveMemoryWarning will be called.

Does this mean I have to replicate the code in both places? Is calling a common method in both places a good approach? Please provide your inputs or approaches on how this is being handled in the industry.

Rob
  • 415,655
  • 72
  • 787
  • 1,044

2 Answers2

4

Yes, if you're supporting iOS versions prior to 6.0, you should remove anything that's dependent upon the view and its controls in viewDidUnload. It's a function of the iOS running on the device. Obviously, if the device is running 6.0 or later, the view won't be unloaded, though. Regardless, you should purge caches and the like in didReceiveMemoryWarning.

You should not replicate the code in the two methods as that's unnecessary. Do view-related cleanup in viewDidUnload and cache-related purging in didReceiveMemoryWarning. And, most importantly, do not copy view-specific cleanup from viewDidUnload (such as setting IBOutlet references to nil, something that Interface Builder used to add to our code) into didReceiveMemoryWarning. If you do and if you get a memory warning in iOS 6, you'll lose IBOutlet references for a view that has not been removed.

See iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks @Rob. That was enlightening and reading from the link you provided completely clarified my question. – Deepu Mukundan Jan 23 '13 at 18:39
  • The question still remains though, will viewDidUnload get called if an app written in iOS6 SDK is running on an iOS5 device? – paiego Mar 21 '13 at 21:25
  • 1
    @paiego Yes, `viewDidUnload` will be called if (a) device is running iOS prior to 6.0; and (b) you receive low memory warning; and (c) the view is not the current view (i.e. you've already done a modal/push to another view controller). It's a function of the device iOS version, not of the version you compiled against. Until you cease to support iOS 5, you have to properly handle `viewDidUnload`. – Rob Mar 21 '13 at 21:51
  • @Rob: Ok, but as jxpx777 noted, didReceiveMemoryWarning has been called since iOS2. Why not just purge the VC's subviews in this method, if it's not attached to the window. i.e. What does viewDidUnload give you that didReceiveMemoryWarning can't? – paiego Mar 21 '13 at 22:38
  • @paiego `viewDidUnload` and `didReceiveMemoryWarning` are for different purposes. `viewDidUnload` is a notification that your view has been released, and let you clean up any references you might have to it (esp useful in non-ARC code). That's very different from `didReceiveMemoryWarning`, which is designed for you to free easily recreated objects, especially useful for non-UI caches and the like. My main point is that if you blithely move the `nil`-ing of `IBOutlet` references from `viewDidUnload` to `didReceiveMemoryWarning`, you'll have a train wreck on your hands when run on iOS 6 device. – Rob Mar 21 '13 at 23:32
  • If you want to discuss further, we should move to chat. Let me know. – Rob Mar 21 '13 at 23:35
  • Unfortunately we disagree with this. I've worked with ViewDidUnload quit a bit now and it is clear to me that viewDidUnload is *only* called in low memory situations. You can add a breakpoint in ViewDidUnload an you'll never hit the breakpoint unless you're experiencing a low memory notification. Apple added viewDidUnload in iOS4, I believe, and it was intended to notify the user that the system has unloaded the views already, and any strong references to subviews should be released. In iOS6, Apple decided to get control back to the app and let it determine when views will be purged. – paiego Mar 22 '13 at 05:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/26690/discussion-between-rob-and-paiego) – Rob Mar 22 '13 at 05:47
1

didReceiveMemoryWarning is available in iOS 2.0 and later, so why not move it from viewDidUnload to didReceiveMemoryWarning for everyone?

jxpx777
  • 3,632
  • 4
  • 27
  • 43
  • 1
    Interface Builder routinely used to add code to `nil` `IBOutlet` references in `viewDidUnload`. That most certainly should not be moved to `didReceiveMemoryWarning` as it would cause problems for iOS 6 users. – Rob Jan 23 '13 at 01:28