How to remember Cocoa memory management:
Think NARC: “New Alloc Retain Copy”. If you are not doing any of those things, you don’t need to
release
.
–Andiih on Stack Overflow
Personally, I like to immediately autorelease
anything I NARC-ed, on the same line. For example:
Foo* pityTheFoo = [[[Foo alloc] init] autorelease];
Admittedly, this makes for some ugly, bracey, lines. But I think it’s worth it, because you never having to worry about calling release
if you also…
Use a @property
(or Setter) Instead of retain
In other words I would write an init
method that looked like:
- (id) init { self = [super init]; if (self) { _ivar = [[Foo alloc] init]; } return self; }
as:
- (id) init { self = [super init]; if (self) { self._ivar = [[[Foo alloc] init] autorelease]; } return self; }
(Or [self setIvar:[[[Foo alloc] init] autorelease]];
if you are one of those folks who hate the dot-syntax.)
It’s debatable if using acessors in init
and dealloc
is a good idea. I even left a comment on that post arguing against it. But since then I’ve done a lot of reflection, and in my experience using a @property
instead of an explicit release
/= nil
solves more problems then it causes. So I think it’s the best practice.
Even if you disagree with me on that point, if the only places you explicitly NARC objects are init
, dealloc
, and setX:
methods then I think you’re doing the right thing.
Cycles!
The last piece of the memory-management puzzle are retain cycles. By far the best advice I’ve seen on them is Mike Ash’s article. Read it.