(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.
The same thing applies to "copy" properties. If you do "self.foo = bar;" when foo is a copy property, you have taken ownership of that object, and need to release it later (hopefully by doing "self.foo = nil;".
On the topic of properties, I also find it helpful to define the property and variable to have different names (e.g., NSString _foo; for the variable and @property (nonatomic, copy) NSString foo; for the property). When mapped through @synthesize foo = _foo;, it avoids confusion about the memory management necessary for a particular value.
that works fine too and prevents any issues with releasing the variable before it gets retained again. objects might hang around in memory a little longer this way, though (for foos != bars)
> 2. When you type "alloc" there is an implied retain.
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."
This article gives bad advice. If you use his examples your program will crash; see tylerc230's comment. Also, it does not follow generally accepted style practices, such as the lack of a space after a closing bracket [[like]this].
> “Typing self.foo releases and nils the variables.”
Yes, if it’s a retain or copy property.
> “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.
it also help when you understand how the dot-notation works in objective-c... it's not like other languages where you are just accessing a member of an object.
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.
A lot of developers (myself included) don't use the dot syntax for property access for this reason and another:
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 '_'
Good article, though it kinda violates rule #1 of Cocoa memory management: don't try to summarize the rules, because you'll probably miss a subtlety. Link to the Apple docs instead.
I lived in doubt of my code until I decided to fully understand memory management. Now that I understand it, it seems simple enough to summarize... but thats the trick
No no no no no... That is absolutely incorrect. Only properties declared "retain" do that.
(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.