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.