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.
“Personally, I like to immediately autorelease anything I NARC-ed, on the same line.”
Man, I thought I was the only one…
Comment by Joel Bernstein — May 19, 2010 @ 11:30 pm
Hi, just asked a question on SO about this. It will eitherGet no notice at allStart a huge debate(most probably) get a few tepid answers and no real conclusions :)
Comment by Daniel Rosenstark (yar) — May 26, 2010 @ 4:37 am
+1 for immediate autorelease. In fact, if you’re using the empty constructor, then I’m pretty sure you can use `new` instead of `alloc, init, autorelease`.
Foo* pityTheFoo = [Foo new];
Comment by Josh — October 4, 2011 @ 9:58 am