From Apple's View Controller Programming Guide / Managing Memory Efficiently;
didReceiveMemoryWarning
Use this method to deallocate all noncritical custom data structures associated with your view controller. Although you would not use this method to release references to view objects, you might use it to release any view-related data structures that you did not already release in your viewDidUnload method. (The view objects themselves should always be released in the viewDidUnload method.)
viewDidUnload
You can use the viewDidUnload method to deallocate any data that is view-specific and that can be recreated easily enough if the view is loaded into memory again. If recreating the data might be too time-consuming, though, you do not have to release the corresponding data objects here. Instead, you should consider releasing those objects in your didReceiveMemoryWarning method.
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html
For didReceiveMemoryWarning, we are recommended to deallocate non-critical data structures. So, what is critical and what is non-critical?
Also, it says to release what we did not already release in viewDidUnload. But when there is a memory warning didReceiveMemoryWarning is called and view could be unloaded then viewDidUnload is called. So, is it talking about the moving those codes to the former event's method(didReceiveMemoryWarning) or am i missing something about the order of events?
For viewDidUnload, we are recommended to care about easily recreating the data when reloading a view. So, if a view is in use and could not be unloaded, why will we release time-consuming data in didReceiveMemoryWarning? After those data released, when user tries to do something within the current view, then it will be time-consuming to load them too.
First of all, these are just guidelines, so if you don't think it makes good sense to release something in didReceiveMemoryWarning
then don't do it. But keep in mind that if your application is the one that is causing the memory warning in the first place then it will eventually just be terminated by the OS.
Re (1): Critical vs. non-critical is entirely your call. Only you can really determine what data you're holding that you consider critical. Though it's probably going to be closely related to your (3), that is, something that is easily recreated is probably not too critical.
Re (2): I don't think the statement is in reference to the order of the calls. As you have realized, in general, viewDidUnload
is going to get called after didReceiveMemoryWarning
(since didReceiveMemoryWarning
can cause viewDidUnload
to be called). As an example, in viewDidUnload
one will release references held to UI elements from a nib. So don't also release them in didReceiveMemoryWarning
.
Re (3): If a view is in use and thus can't be unloaded, then yes, obviously it doesn't necessarily make much sense to release it in didReceiveMemoryWarning
. However, you may actually have instances where a view couldn't be unloaded, but is known to not be visible (not terribly normal), in which case it might make sense to unload it's data and recreate it when the view is visible once again.
Additionally, I agree the "Instead, you should consider..." remarks are a bit odd, but again I think the point of recommending the data be released in didReceiveMemoryWarning
stems from the fact that if you're receiving those warnings then your own app might be in danger of being terminated. So while it is currently the case that viewDidUnload
probably is always called as the result of a memory warning, that may not always be the case in the future and so conceptually it makes more sense to release the data in didReceiveMemoryWarning
itself. In didReceiveMemoryWarning
you KNOW there is memory pressure, in viewDidUnload
you may not. So while it's true that the data will then be expensive to recreate, that might be better than having your app terminated. To the user it will appear as though the app crashed.
My own personal approach to those methods is generally this:
viewDidLoad
.viewDidLoad
is called again (or some other app specific event). Do NOT release anything that I can't possible recreate.The apps I'm building are graphics-intensive, both in terms of layout chrome, and in the images associated with the data I'm downloading and displaying.
My didReceiveMemoryWarning
methods are ALL about determining which images I'm holding in memory but not currently displaying, and dropping them from memory. The other piece of that is, you need to check before displaying an image whether it's still around, and lazy-load it if not.
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