There are several aspects to be considered here, some of them are already mentioned.
First of all, the underscore is just a legal character and part of the name. It is more or less just a convention that the local iVar _foo
corresponds to the property foo
. That is always the case when
- You have them autosynthezised. (no
@synthesize
statement) Then the iVar is generated automatically with a leading underscore. (in newer versions of Objective C)
- You intentionally declare the iVar
_foo
and extend the @synthesize statement in that way that it refers to _foo
when it is named foo
. You could as well declare the property foo
and the ivar bar
and link them in the @synthezise
or in custom getters. This were just far away from any convention and therefore not generally recomended.
Example: @synthesize foo = _foo;
- You provide custom getters and setters and access the property. Again, you could link any iVar with the property or even set a number of them in response to the input etc. pp.
The property foo corresponds to the ivar foo when
- You use
@synthezise
without providing the name of the ivar. Just @synthesize foo
;
(I think, depending on the version of ojective-c, that works with or without explizit declaration of the ivar foo, but I would not sign that in blood)
In general I recommend to stick to the underscore pattern, although I don't do that always myself. The advantage is that the separation between the ivar and the property is more visible to the programmer which helps avoiding mistakes. Especially local parameters of the same name (quite common) would not hide the ivar.
Example with foo
:
foo = @1; //This refers to the iVar foo.
self.foo = @1; //This calls the setter.
[self setFoo:@1]; //This calls the setter.
someVar = [self foo]; // This calls the getter.
foo = foo; // This would not work assuming that foo is a local parameter of the method.
self->foo = foo // This is not good style but a workaround for the line above in that situation. This accesses the ivar directly on the left side of the equation, not its setter.
self.foo = foo; // This is fine when foo is the local parameter.
The same with _foo, where it is just more clear to the programmer:
_foo = @1; //This refers to the iVar _foo.
self.foo = @1; //This calls the setter.
[self setFoo:@1]; //This calls the setter.
someVar = [self foo]; // This calls the getter.
_foo = foo; // This would work nicely assuming that foo is a local parameter of the method.
self->_foo = foo // No need for doing that. It is rather C style anyway and not that common in Obj-C.
self.foo = foo; // This, too, is fine when foo is the local parameter. Clearly uses the setter.