
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 the iPhone OS, 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 the iPhone OS 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, the iPhone OS tries to give the running application the memory it needs — using 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.
When the system dispatches a low-memory notification to your application, it is something you must pay attention to. If you don’t, it is a reliable recipe for disaster. (Think of your low-fuel light going on as you approach a sign that says "Next services 100 miles.") 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.
✓ Override the didReceiveMemoryWarning: method in your custom UlViewController subclass. The view controller could then release views — or even other view controllers — that are off-screen.
✓ Register to receive the UIApplicationDidReceiveMemoryWarning Notification: notification. A model object could then release data structures or objects it owns that it doesn’t need immediately and can re-create later.
UIKit Your code
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, while I will mention a strategy for implementing the view controller’s didReceiveMemoryWarning: in Chapter 14, this is something that is dependent on your application’s architecture. That means you’ll need to explore it on your own.
Not freeing up enough memory will result in the iPhone’s OS sending your application the applicationWillTerminate: message and shutting you down. For many applications, though, the best defense is a good offense, and you need to manage your memory effectively and eliminate any memory leaks in your code.
When you create an object — a window or button for example — memory is allocated to hold that object’s data. The more objects you create, the more memory you use, and the less there is available for additional objects you might need. Obviously, it’s important to make available (deallocate) the memory that an object was using when the object is no longer needed. This is what is meant by memory management.
The Objective-C language — the application-programming language used to develop iPhone applications — uses reference counting to figure out when to release the memory allocated to an object. It’s your responsibility (as a programmer) to keep the memory-management system informed when an object is no longer needed.
Various events besides termination can interrupt your application to allow the user to respond — for example, incoming phone calls, SMS messages, calendar alerts, or the user pressing the Sleep button on an iPhone. Such interruptions may only be temporary. If the user chooses to ignore an interruption, your application continues running as before. If the user decides to answer the phone or reply to an SMS message, however, your application will be terminated.
Launch, initialize, process, terminate, launch, initialize, process, terminate. . . it has a nice rhythm to it, doesn’t it? And those are the four major stages of the application’s life cycle. 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 interruptions and memory management.
Getting stuff to (safely) shut down is another application delegate responsibility. To handle termination, the application delegate implements the delegate method applicationWillTerminate: to save any unsaved data or key application state (where the user is in the application — the current view and stuff like that) to disk. (Okay, I know, the disk in the iPhone is not really a disk; it’s a solid state drive that Apple calls a disk, but if it calls it that, I probably should, too, just so I don’t confuse too many people.). You can also use this method to perform additional cleanup operations, such as deleting temporary files.
After a user launches your application, the functionality provided in the UIKit framework manages most of the application’s infrastructure. Part of the initialization process mentioned in the previous section involves setting up the main run loop and event handling code, which is the responsibility of
The next step is for the UIApplication to send the ReturnMeToApp Delegate applicationDidFinishLaunching: message. Step 5 in Figure 6-6 represents what happens when the applicationDidFinish Launching: method is invoked.

In only a few pages, you’ve accomplished quite a bit. I want to emphasize, as you will see, that what I have done is not just a design. What you see here is the specification for "code" that will take what I have laid out in Interface Builder and create the objects that will implement it at runtime.
One of the design goals for the ReturnMeTo application was to make it obvious to someone who found my iPhone that he or she should touch the application icon.