Memory management with iOS

In creating my first iPhone app which uses the Address Book, I discovered the world of memory management with iOS.  I wanted to share a few things I’ve learned and provide lots of links for your reference.

ARC, retain counts and CFRelease

Admittedly, if you stick strictly to Foundation code, you probably don’t need to be concerned too much about what happens under the hood.   With the introduction of ARC (Automatic Reference Counting), iOS takes care of much of this for you.  It’s when you also need to deal with Core Foundation (CF), which the Address Book uses, that things become tricky.   CF has a concept of object ownership and memory management using retain counts.   An object can have multiple owners (retain count > 1), but when you are done with that object the retain count had better be zero or you’ll create memory leaks.    To accomplish this, you need to use CFRelease().

Over releasing, Zombie Objects, CFGetRetainCount

A typical problem I ran across was calling CFRelease too many times (over releasing).    When you try to access an object that has been over released, you’ll get a run time message with “Program received signal: EXC_BAD_ACCESS”.   To get a more meaningful message that will will show the type of object with the bad access, you can enable Zombie objects with ⌥ ⌘ R.    This is discussed in the post How do I set up NSZombieEnabled in Xcode 4?

Enabling Zombie Objects

If you want to check the retain count on an object, you can log the result of calling CFGetRetainCount(<object>).    Note that you if you call this function on an object that has been fully released, your program will crash.

Mixing Foundation and Core Foundation Code

iOS makes it fairly easy to mix Foundation and CF code.   They introduced a concept called Toll-Free Bridging to make this easier.   Many types (arrays,dictionaries, etc.) can be used interchangeably.  What you need to think about is who owns the object after the conversion.   If you want to convert with no change in ownership (I don’t use this often), then use __bridge.  Example:

NSString *str = @"hello";
CFStringRef str_cf = (__bridge CFStringRef)str; // Foundation to CF
NSString *str2 = (__bridge NSString *)str_cf; // And back again

When converting from Foundation to CF, use CFBridgingRetain().  Ownership transfers to CF which means that you are responsible for releasing it when done.

NSString *str = @"hello";
CFStringRef str_cf = (CFStringRef)CFBridgingRetain(str);

// Do something with str_cf

CFRelease(str_cf);

When converting from CF to Foundation, use CFBridgingRelease.  Ownership transfers to Foundation.

CFStringRef str_cf = CFSTR("hello");
NSString *str = (NSString *)CFBridgingRelease(str_cf);

Returning a Core Foundation object from Foundation method

This one tripped me up for a while.  Consider the following:

+ (void)populate
{
    CFStringRef name_cf = [self getString];
    // Do something with name_cf
    CFRelease(name_cf);  // Over release!
}

+ (CFStringRef)getString
{
    CFStringRef name_cf = CFStringCreateWithFormat(...

    return name_cf;
}

The problem here is that we didn’t transfer ownership of name_cf inside getString to the caller! So how do we cause the code in getString to release its retain count on name_cf when returning the string to populate?

After digging for a while, I discovered that I only needed to rename getString() to newString(). iOS then assumes that we want a transfer of ownership to the calling function. See the documentation Advanced Memory Management Programming Guide.  Look for the section “You own any object you create”.      I first ran across the answer at Stack Overflow with these posts:

How to release an locally created object, while it using as return object

Best IOS Memory management @ Function Call Returning allocated object

Coming up – Instruments, Heapshots, etc.

In my next post, I’ll share some of what I’ve learned with using Instruments and Heapshots for memory leak debug.

Advertisements

One response to “Memory management with iOS

  1. Pingback: The development of Contacts2Web | Finalize.com: My journey with iOS and other code adventures

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s