I believe the example is wrong, or ill-posed. A proper example should be
@property (copy) NSString *ponyName; // not name!
...
@synthesize ponyName; // not name!
...
- (void) setPonyInfoFromPropertyDict: (NSDictionary *) ponyProperties {
NSString *name = [ponyProperties objectForKey: @"Name"];
ponyName = name;
//self.ponyName = name; // will solve the problem
}
name
can be a mutable string, so if you want to make sure it won't change after it has been assigned you have to copy it. You can use a copy
property for the task, but doing
ponyName = name;
you are not using the setter at all.
self.ponyName = name;
will fixe the issue and name
will be copied by the setter.
Discussion
One of the most common mistakes when programming in Objective-C is to access the ivar directly instead of using a setter/getter.
Accessory methods are important since they typically provide a lot of logic for accessing and setting the ivars, most notably concerning memory management. Nowadays their implementation is greatly simplified by the ARC compiler, but, in case you use MRC, accessory methods are crucial in helping to handle the release
/retain
balance.
An example which is still valid under ARC, is when you declare a copy
property. In such case the synthesized setter will take care of copying the argument before assigning to the ivar, so when you do
[self setMyCopyProperty:aNewThing];
or equivalently
self.myCopyProperty = aNewThing;
aNewThing
will receive a copy
message, before being assigned to the backed ivar.
On the other hand if you synthesize the property like this
@synthesize myCopyProperty;
you might accidentally find yourself doing
myCopyProperty = aNewThing;
which won't copy aNewThing
, since you are accessing the ivar directly.
In order to not confuse ivars and accessory methods, it's then become a standard convention to prefix ivars with an underscore, i.e. synthesize them like
@synthesize myCopyProperty = _myCopyProperty;
In this way, if you accidentally do
myCopyProperty = aNewThing;
it won't compile as there's no such thing as a myCopyProperty
ivar, probably saving you from a terrible headache when you are debugging memory-related issues. If instead you know what you are doing and you really want to access the ivar (perhaps in a init
method), you can simply do
_myCopyProperty = [aNewThing copy];
which is a lot more explicit about your intention of not using a setter.
Finally, it's probably worth noting that with modern versions of the clang
compiler you can avoid the explicit @synthesize
as it will be automatically inserted in the form of
@synthesize foo = _foo;
Some exceptions apply, and you can read more about it here: When should I use @synthesize explicitly?