iOS 5 is coming soon, and introduces ARC. ARC will make Objective-C memory management significantly simpler. But, it will be a long time before iOS 5 is ubiquitous, and I’m not sold on the subset of ARC that will be available for iOS 4. So, in the meantime, I thought people might benefit from seeing the conventions I use to keep Objective-C memory management simple. Most iOS developers probably already follow something close to this, but it doesn’t hurt to have it written out.
If you follow these five simple rules, you should pretty much never get a memory leak or a crash from over-releasing.
1. Always declare @properties for your object instance variables
If you’re putting an instance variable on a class and it’s an object, declare a property for it.
1 2 3 4 5 6 7 8 9 10
By default, you should always declare your object properties as
If you’re declaring a property for an object that’s expected to be immutable, but has a mutable subclass (for example, if you’re declaring an
NSArray property, which has the
NSMutableArray subclass), declare it as
copy instead of
If you’re declaring a property for an object that is guaranteed to be retained elsewhere (for example, a delegate, or something that you’re also storing in an array and just need a convenient shortcut to), you can declare it
assign. Be very careful with this though. If you’re unsure, just do
You’ll also need to
@synthesize all these properties in your
1 2 3 4 5 6 7 8 9 10 11 12
Finally, you’ll need to release all of the
copy properties (but not the
assign properties) in your
dealloc. This is the only place in your code where you should refer to your properties without
self. (which means you’re actually accessing the instance variables rather than the properties).
1 2 3 4 5 6 7 8 9 10 11 12
2. Always use
self when accessing a property
If you don’t use
self, you will be accessing the underlying instance variable directly, rather than going through the @synthesized getter/setter.
1 2 3 4
If you skip the @synthesized getter/setter, you skip the memory management rules you defined in your
@property, which will lead to problems. The only exception to this is mentioned in rule 1: in your
dealloc method, when releasing the object.
3. Make sure all newly-created objects are autoreleased
There is a bit of disagreement on the community on this one, but I have yet to hear a compelling argument for all but the most extreme cases, so we’ll go with the side that makes life easier. Whenever you create a new object, make sure it is autoreleased.
The convention for this is as follows: all methods that return objects return autoreleased objects, unless the method name starts with
copy. For example:
If you create an object with a method that starts with
copy, make sure you explicitly tell it to autorelease:
This will save you a lot of headaches. Any objects that you don’t want to keep will be released automatically. Any objects that you do want to keep should be assigned to a property, and since the property is
copy (as mentioned in rule 1), they will be retained and kept automatically.
4. Never call
retain on anything
retain is not called once in all the lines of Objective-C code in my current code base. If you find yourself needing to explicitly retain an object, create a
copy property for it instead (as mentioned in rule 1) and assign it to that property.
5. Never call
release on anything (except in
If you’re following rule 4, there should never be a time when you explicitly need to release an object, except in your class’s
dealloc method (as mentioned in rule 1).
If you follow all these rules, you should never have to think about memory management. If you deviate from any of them, you could end up in weird tough-to-debug situations, so try your hardest not to. If you find yourself in a situation where you think you absolutely need to deviate, write a comment on this post explaining your situation, and I’ll see if I can help.