This is something any experienced Cocoa developer has been asked at least half a dozen times:
“What’s the best way to learn Objective-C/Cocoa?”
I have two answers to this question:
- Be curious
- Don’t be satisfied
He goes on to finish with the following epithet:
- Know what a pointer is.
- Memorize the memory management rules.
- Never invoke
-retainCount.
The second item there is the one I most frequently hear is ‘really difficult’ to understand. It’s not. It’s really not. It looks like this:
- Only the owner of an object needs to think about its memory management.
- You only own an object if you get it from a method whose name begins with any one of:
alloc, including+allocWithZone:new, including+newSomethingSomethinginit, including-initWithSomeParameter(er, no, it doesn’t. I’m being stupid. Sorry.)copy, including-copyWithZone:or-mutableCopyor-mutableCopyWithZone:
- If the object doesn’t come from a method matching those rules, you don’t own it.
Edit: Specifically, the method must either be one of the above words, or begin with one followed by an uppercase letter. This means that +newSomething returns an owned reference, but +newestSomething does not. Thanks to Dave DeLong for reminding me of this via email.
It’s that simple. If you call something including alloc, new, init, or copy, then you must use -release (or -autorelease) to balance that call. If you don’t call one of those methods, you Just Don’t Care.
How about CoreFoundation? That’s even simpler: you own an object if it comes from a method containing Create. The same thing could be said about Copy, but CF’s copy constructors are always careful to frequently already contain Create, so we don’t need to. Anything named using Get returns an already-managed reference, so you don’t need a CFRelease for it.
Edit: I’m reminded by Peter Hosey that many CF-style APIs outside of CoreFoundation itself tend to use Copy without Create, for instance those in CoreGraphics. Note however that not everything that looks like a CF object really is one— many are just C wrappers around Carbon-era C++ code.
See? Easy. A list of four keywords in Objective-C code indicate the only times you need to ever think about memory management. And one keyword in CoreFoundation to tell you the same.
Now, there are exceptions— usually when something missed the boat, or when an existing API needed to be changed to fix an internal memory-management issue. The documentation will tell you about these very rare cases, but the best way to catch them for now is judicious use of Build & Analyze. The Clang compiler’s static analysis tool knows all about these rules, and can be told about any differences to them by any API. It will tell you explicitly if you’ve released something you don’t own, or have failed to release something you do own. Use it. Love it.
Memory management in Cocoa isn’t difficult. There are rules, but they’re simple and easy to remember. The main thing to remember is:
Don’t over-think it