How Memory Management Works on iOS
gaiagps.com
gaiagps.com
No no no no no... That is absolutely incorrect. Only properties declared "retain" do that.
@property (nonatomic, assign) NSObject *foo; // doesn't retain
@property (nonatomic, copy) NSObject *bar; // doesn't retain
@property (nonatomic, retain) NSObject *baz; // *does* retain
(The 'nonatomic' isn't related to the retain/no-retain semantics, but most properties are declared nonatomic, as atomic properties have some locking overhead.)On a side note, a discussion of iOS/Mac memory management isn't very useful if it doesn't talk about how autorelease pools work.
Also, hopefully this post is useful as is at least for beginners, though adding information on autorelease pools would be good for sure.
- (void) setFoo:(NSString*) bar {
[foo release];
foo = [bar retain];
}
should be: - (void) setFoo:(NSString*) bar {
if(bar == foo)
return;
[foo release];
foo = [bar retain];
}
so that you can do without crashing: obj.foo = obj.foo; - (void) setFoo:(NSString*) bar {
[foo autorelease];
foo = [bar retain];
}
which I expect to do nothing (retain count is unchanged) when foo == bar.
I do it for concision, am I missing something? - (void) setFoo:(NSString*)bar {
[bar retain];
[foo release];
foo = bar;
}
which harmlessly increments and decrements for self-assignment.It's not quite that simple. The official rule from Apple's Memory Management Programming Guide most succinctly states "You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message."
> “Just typing foo = nil is a memory leak.” Yes, if you had retained the object, but not if it were a weak reference. Admittedly, this is a semi-rare scenario.
foo = object.bar;
is syntactic sugar for
foo = [object bar]; //where 'bar' is a method call
and object.foo = bar;
is syntactic sugar for:
[object setFoo:bar];
I dealt with a lot of goofy memory errors trying to figure out why using 'self.foo' and just 'foo' inside of a class acted differently. Now it makes much more sense.x.foo = z; becomes an ambiguous statement in obj-c when you use dot access. Is x an object? then this is a message send. Is x a struct? then this is an assignment.
Typically in my interface file, I explicitly define my member variables with a leading '_';
@interface Foo { NSObject_bar; }
@property(nonatomic, retain) NSObject bar;
@implementation Foo @synthesize bar=_bar; @end
And if I want to access bar I use [x bar], [x setBar:y]; it is easy to visually scan for direct use of member values by looking for the leading '_'