I am new in objective c and I have some doubts. I've seen that you can access to the properties of a class like var->myProperty and like that too variable.myProperty, but I do not know what the difference between the 2. I searched a lot in internet and really have not found a conclusive answer.
Sorry if I have spelling errors, thanks in advance.
The obj->foo
syntax accesses the ivar foo
of obj
whereas obj.foo
accesses the property (defined by @property
). The main difference is that obj->foo
does not use any getters/setters and writes to the ivar directly.
For example, if you defined the property like this
@property (atomic, strong, readonly) SomeClass *foo;
Modern Objective-C compilers will automatically create an ivar _foo
and the property foo
for you (without the need of declaring the ivar and @synthesize
ing the property.
obj.foo
will then automatically use the atomic
getter and will make the property readonly
(ie no setter). Using the ivar syntax obj->_foo
, you are reading the property non-atomically(!) and you can even write it (remember, the property is readonly
!).
Usually it's very easy: Always use the property syntax, except in init
and dealloc
, there you use the ivar syntax. Obviously when you are actually implementing a getter or a setter yourself, that's another place to use the ivar syntax. (thanks to @godel9). (Remember: That's a rough guideline, there are other use-cases where you might want direct ivar access).
EDIT: Because of some critique in the comments: It's true that the dot syntax can also be used without declaring something as @property
, eg some use array.count
instead of [array count]
(for NSArray *array
). But given that the OP asked about properties vs ivars, that was certainly not asked. Also note that for a given @property ... SomeClass *foo
the ivar is not necessarily _foo
but that's would be the auto-generated ivar name in recent ObjC compilers (with @synthesize
you can map properties to arbitrary ivars).
There are three cases to consider:
someObject.something
is the dot syntax. It is exactly equivalent to [someObject something]
in terms of behavior. It is a method call. Note that something
does not have to be declared via an @property
. That is, someArray.count
or someString.length
are both syntactically valid.
self->something
is accessing an ivar directly. It is a very rarely used syntax; rare is in pretty much never. Instead, just access the ivar directly using something =
or [something doSomething]
. No need for the ->
.
otherObject->something
is grubbing around otherObject
's instance variables directly. Bad programmer. No donut. Don't do that. It breaks encapsulation and leads to extremely fragile, hard to maintain, code.
A note on @property
declarations. If you have:
@property (atomic, strong, readonly) SomeClass *foo;
And if you let the compiler automatically @synthesize
everything, it will create an instance variable named _foo
.
You should use direct access in your init
and dealloc
methods, but -- typically, though not always -- use the setter/getter everywhere else. I.e. in your init
you would do _foo = [SomeClass someClassWithSomeMagicValue:42]
(assumes ARC, so no retain
needed). Everywhere else, you would do [[self foo] castMagic];
.
look at Pointers in objective-c
http://www.drdobbs.com/mobile/pointers-in-objective-c/225700236