You are previewing Learning iPhone Programming.

Learning iPhone Programming

Cover of Learning iPhone Programming by Alasdair Allan Published by O'Reilly Media, Inc.
  1. Learning iPhone Programming
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. A Note Regarding Supplemental Files
    3. Preface
      1. Who Should Read This Book?
      2. What Should You Already Know?
      3. What Will You Learn?
      4. What’s in This Book?
      5. Conventions Used in This Book
      6. Using Code Examples
      7. How to Contact Us
      8. Safari® Books Online
      9. Acknowledgments
    4. 1. Why Go Native?
      1. The Pros and Cons
      2. The Release Cycle
      3. Build It and They Will Come
    5. 2. Becoming a Developer
      1. Registering As an iPhone Developer
      2. Enrolling in the iPhone Developer Program
      3. The Apple Developer Connection
      4. Installing the iPhone SDK
      5. Preparing Your iPhone or iPod touch
    6. 3. Your First iPhone App
      1. Objective-C Basics
      2. Creating a Project
    7. 4. Coding in Objective-C
      1. Declaring and Defining Classes
      2. Memory Management
      3. Fundamental iPhone Design Patterns
      4. Conclusion
    8. 5. Table-View-Based Applications
      1. Simplifying the Template Classes
      2. Creating a Table View
      3. Building a Model
      4. Connecting the Controller to the Model
      5. Adding Navigation Controls to the Application
      6. Adding a City View
      7. Edit Mode
    9. 6. Other View Controllers
      1. Utility Applications
      2. Tab Bar Applications
      3. Modal View Controllers
      4. The Image Picker View Controller
    10. 7. Connecting to the Network
      1. Detecting Network Status
      2. Embedding a Web Browser in Your App
      3. Sending Email
      4. Getting Data from the Internet
    11. 8. Handling Data
      1. Data Entry
      2. Parsing XML
      3. Parsing JSON
      4. Regular Expressions
      5. Storing Data
    12. 9. Distributing Your Application
      1. Adding Missing Features
      2. Building and Signing
      3. Submitting to the App Store
      4. Reasons for Rejection
    13. 10. Using Sensors
      1. Hardware Support
      2. Using the Camera
      3. The Core Location Framework
      4. Using the Accelerometer
      5. Using the Digital Compass
      6. Accessing the Proximity Sensor
      7. Using Vibration
    14. 11. Geolocation and Mapping
      1. User Location
      2. Annotating Maps
    15. 12. Integrating Your Application
      1. Application Preferences
      2. Custom URL Schemes
      3. Media Playback
      4. Using the Address Book
    16. 13. Other Native Platforms
      1. PhoneGap
      2. MonoTouch
    17. 14. Going Further
      1. Cocoa and Objective-C
      2. Web Applications
      3. Core Data
      4. Push Notifications
      5. In-App Purchase
      6. Core Animation
      7. Game Kit
      8. Writing Games
      9. Look and Feel
      10. Hardware Accessories
    18. Index
    19. About the Author
    20. Colophon
    21. SPECIAL OFFER: Upgrade this ebook with O’Reilly

Memory Management

The way memory is managed in Objective-C on the iPhone is probably not what you’re used to if you’re coming in from a language such as Java. If you’re writing an application in Objective-C for the Mac, you have the option of enabling garbage collection; however, on the iPhone you are restricted to using reference counting. This isn’t as bad as it seems, and sticking to a few simple rules means that you can manage the memory that is allocated.

Creating Objects

You can create an object in two ways. As shown in the following code, you can manually allocate the memory for the object with alloc and initialize it using init or an appropriate initWith method (e.g., NSString has an initWithString method):

NSString *string = [[NSString alloc] init];
NSString *string = [[NSString alloc] initWithString:@"This is a string"];

Alternatively, you can use a convenience constructor method. For instance, the NSString class has a stringWithString class method that returns an NSString object:

NSString *string =  [NSString stringWithString:@"This is a string"];

In the preceding two cases, you are responsible for releasing the memory you allocated with alloc. If you create an object with alloc, you need to release it later. However, in the second case, the object will be autoreleased. You should never manually release an autoreleased object, as this will cause your application to crash. An autoreleased object will, in most cases, be released at the end of the current function unless it has been explicitly retained.

The Autorelease Pool

The autorelease pool is a convenience that defers sending an explicit release message to an object until “later,” with the responsibility of freeing the memory allocated to objects added to an autorelease pool devolved onto the Cocoa framework. All iPhone applications require a default autorelease pool, and the Xcode template inside the main.m file creates it for us:

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];1
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];2
    return retVal;

The default autorelease pool is set up prior to entering the main event loop.


The default autorelease pool is drained after exiting the loop.

An additional inner autorelease pool is created at the beginning of each event cycle (i.e., iteration through your application’s event loop), and is released at the end.

The need for and existence of autorelease makes more sense once you appreciate why it was invented, which is to transfer control of the object life cycle from one owning object to another without immediately deallocating the object.

The alloc, retain, copy, and release Cycle

Although the autorelease pool is handy, you should be careful when using it because you unnecessarily extend the time over which the object is instantiated, thereby growing your application’s memory footprint. Sometimes it makes a lot of sense to use autoreleased objects. However, beginning Cocoa programmers often overuse convenience constructors and autoreleased objects.


Apple, writing in its Cocoa Fundamentals guide, officially discourages the use of autorelease objects on the iPhone due to the memory-constrained environment on the device, stating that “Because on iPhone OS an application executes in a more memory-constrained environment, the use of autorelease pools is discouraged in methods or blocks of code (for example, loops) where an application creates many objects. Instead, you should explicitly release objects whenever possible.”

When handling memory management manually using the retain count and the alloc, retain, and release cycle (see Figure 4-1), you should not release objects you do not own. You should always make sure your calls to retain are balanced by your calls to release. You own objects that you have explicitly created using alloc or copy, or that you have added to the retain count of the object using retain. However, you do not own objects you have created using convenience constructors such as stringWithString.

The alloc-retain-release cycle; an object is allocated, retained, and then released twice, bringing the reference count back to zero and freeing the memory

Figure 4-1. The alloc-retain-release cycle; an object is allocated, retained, and then released twice, bringing the reference count back to zero and freeing the memory

When releasing the object, you have the option of sending it either a release message or an autorelease message:

[anObject release];
[anObject autorelease];

Sending a release message will immediately free the memory the object uses if that release takes the object’s retain count to zero, while sending an autorelease message adds the object to the local autorelease pool. The object will be released when the pool is destroyed, normally at the end of the current function.

If your object is a delegate of another object, you need to set the delegate property of that object to nil before you release your original object.

The dealloc Method

The dealloc method is called when an object is released. You should never call this method directly, but instead send a release message to the object, because the object may contain references to other objects that will not be deallocated.

As we did in the HelloWorldViewController class, you should always override the dealloc method in your own objects and in release objects you have created or retained:

- (void)dealloc {
    [label release];
    [button release]
    [super dealloc];

In this method, we released the label and button instance variables. We then called the dealloc method of the superclass. It is entirely permissible to send a release message to a nil object.

Responding to Memory Warnings

Your code must respond to memory warnings. Let’s look at the HelloWorldViewController implementation from Chapter 3 again. It implements the didReceiveMemoryWarning method:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

This is where you should release any large blocks of memory—for instance, image or web caches—that you are using. If you ignore a memory warning, your application may crash. The iPhone does not have any sort of virtual memory or swap file; when the device runs out of memory there really is no more memory to allocate. It’s possible, and advisable, to test your application by simulating a memory warning in iPhone Simulator, which you can do by selecting HardwareSimulate Memory.

The best content for your career. Discover unlimited learning on demand for around $1/day.