- Creating New Projects
- Building Hello World the Template Way
- Using the Simulator
- The Minimalist Hello World
- Converting Interface Builder Files to Their Objective-C Equivalents
- Using the Debugger
- Memory Management
- Recipe: Using Instruments to Detect Leaks
- Recipe: Using Instruments to Monitor Cached Object Allocations
- Analyzing Your Code
- Building for the iOS Device
- Detecting Simulator Builds with Compile-Time Checks
- Performing Runtime Compatibility Checks
- Pragma Marks
- Preparing for Distribution
- Over-the-Air Ad Hoc Distribution
- Submitting to the App Store
- Summary
Memory Management
iOS does not offer garbage collection. It relies on a reference counted memory management system. The new LLVM ARC extensions introduce automated reference counting, letting the compiler take care of many management issues for you. ARC automates when objects are retained and released, simplifying development. That doesn’t mean you don’t have to worry about memory:
- Even with ARC, you remain responsible for letting go of resources that create low-memory conditions. If you hold onto lots of multimedia assets such as video, audio, and images, you can exhaust memory—even in ARC-compiled applications.
- Many developers continue to use manual retain/release (MRR) development, especially to avoid refactoring production-critical code. Using MRR means you must control when objects are created, retained, and released in that code because ARC will not handle that for you.
- ARC does not automatically extend to Core Foundation and other C-based class code. Even if CF classes are toll-free bridged, ARC does not assume control of their instances until they are bridged into the Objective-C world.
As a developer, you must strategize how to react to low-memory conditions. Use too much memory and the iPhone warns your application delegate and UIViewControllers. Delegates receive applicationDidReceiveMemoryWarning: callbacks; view controllers get didReceiveMemoryWarning. Continue to use too much memory and the iPhone will terminate your application, crashing your user back to the iOS home screen. As Apple repeatedly points out, this is probably not the experience you intend for your users, and it will keep your application from being accepted into the App Store.
You must carefully manage memory in your programs and release that memory during low-memory conditions. Low memory is usually caused by one of two problems: leaks that allocate memory blocks that can’t be accessed or reused, and holding onto too much data at once. Even on newer iOS devices, such as the iPad 2, your application must behave itself within any memory limits imposed by the operating system.
Every object in Objective-C is created with an integer-based retain count. So long as that retain count remains at 1 or higher, objects will not be deallocated. That rule applies in ARC code just as it applies in MRR. It is up to you as a developer to implement strategies that ensure that objects get released at the time you will no longer use them.
Every object built with alloc, new, or copy starts with a retain value of 1. Whether developing with ARC or MRR, if you lose access to an object without reducing the count to 0, that lost object creates a leak (that is, memory that is allocated and cannot be recovered). The following code leaks an array:
NSArray *leakyArray = [NSArray arrayWithObjects:@"Hello", @"World", nil]; CFArrayRef leakyRef = (__bridge_retained CFArrayRef) leakyArray; leakyRef = nil;