The Managed Memory Model Design Pattern
Launch, initialize, process, respond, terminate.... it has a nice rhythm to it, doesn't it? Those are the five major stages of the application's lifecycle. But life isn't simple - and neither is runtime. To mix things up a bit, your application will also have to come to terms with memory management.
There's one other design pattern: the Managed Memory Model. One of the main responsibilities of all good little applications is to deal with low memory. So, the first line of defense is (obviously) to understand how you as a programmer can help them avoid getting into that state.
In iOS, each program uses the virtual-memory mechanism found in all modern operating systems. But virtual memory is limited to the amount of physical memory available. This is because iOS doesn't store changeable memory (such as object data) on the "disk" to free up space and then read it in later when it's needed. Instead, iOS tries to give the running application the memory it needs, freeing memory pages that contain read-only contents (such as code), where all it has to do is load the "originals" back into memory when they're needed. Of course, this may be only a temporary fix if those resources are needed again a short time later.
If memory continues to be limited, the system may also send notifications to the running application, asking it to free up additional memory. This is one of the critical events that all applications must respond to.
Observing low-memory warnings
When the system dispatches a low-memory notification to your application, it's something you must pay attention to. If you don't, it's a reliable recipe for disaster. UIKit provides several ways of setting up your application so that you receive timely low-memory notifications:
- Implement the applicationDidReceiveMemoryWarning: method of your application delegate. Your application delegate could then release any data structure or objects it owns - or notify the objects to release memory they own. Apple recommends this approach.
- Override the didReceiveMemoryWarning: method in your custom
UIViewController subclass. The view controller could then release
views - or even other view controllers - that are off-screen. For example,
in your new project (DeepThoughts) created with the View-based
Application template, the template already supplies the following in
DeepThoughtsViewController.m, ready for you to customize:
- (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } - (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; }
- Register to receive the UIApplicationDidReceiveMemoryWarning Notification: notification. Such notifications are sent to the notification center, where all notifications are centralized. An object that wants to get informed about this notification registers itself to the notification center by telling which notification it wants to get informed about and which method should be invoked when the notification is raised. A model object could then release data structures or objects it owns that it doesn't need immediately and can re-create later.
Each of these strategies gives a different part of your application a chance to free up the memory it no longer needs (or doesn't need right now). As for how you actually get these strategies working for you, that's dependent on your application's architecture. That means you need to explore it on your own.
Not freeing up enough memory will result in iOS sending your iPad application the applicationWillTerminate: message and shutting your app down. For many apps, though, the best defense is a good offense, and you need to manage your memory effectively and eliminate any memory leaks in your code. A memory leak is how programmers describe a situation in which an object is unable to release the memory it has acquired - it can diminish performance by reducing the amount of available memory.