tags:

views:

767

answers:

3

Assume that I have this piece of code:

@interface Foo : NSObject {
    Bar *bar;
}

@property (retain, nonatomic) Bar *bar;

@end

When using this field/property, is there any difference between lines:

[self.bar doStuff];

and

[bar doStuff];

?

When doing assignment, property method will perform correct retaining, but what about the read access to the property, as described above? Is there any difference?

A: 

A synthesized (or correctly hand-written) nonatomic accessor will be functionally equivalent to

- (Bar *)bar
{
    return bar;
}

so there is no functional difference between your two examples.

However, outside of -dealloc or your initializers, consistently accessing the property via its accessor is a good idea.

Jim Correia
+1  A: 

Using the accessor self.bar is translated into a method call: [self bar]. The period syntax is just for looks. Accessing the member variable directly doesn't involve an extra function call, and is therefore slightly faster. It really only matters if you're accessing it within a loop, or in some process where that difference will add up. (On the iPhone) The setters created for properties also have some extra overhead for doing key value coding. A KVO notification is sent when you call "setBar:" or say "self.bar =" , so calling it over and over will result in a flood of notifications.

Jim is right, though - there's no functional difference between a nonatomic @property and a direct use of the variable in your code. Unless you're really concerned with the speed, using the property is probably your best bet.

Ben Gotow
No. Consider a derived class that overrides -(Bar*)bar;
Nikolai Ruhe
Good point Nikolai - since an overridden -(Bar*)bar may add extra business logic or return something other than bar, using the property may not be equivalent to a direct reference to the variable. Thanks for pointing that out!
Ben Gotow
Just to be clear: the overhead your talking about does not depend on the setter being created through a @synthesize statement. Even if you implement them yourself notifications will be sent if an observer is registered. This is accomplished through isa swizzling.
nschmidt
+8  A: 

There is a big difference. [self.bar doStuff] is equivalent to [[self bar] doStuff]

[bar doStuff] is equivalent to [self->bar doStuff]

The former uses the accessor method, the latter just accesses the instance variable bar directly.

If you use the @synthesize directive on your bar property, the compiler will generate two methods for you:

- (void)setBar:(Bar*)b;
- (Bar*)bar;

Also note, that the compiler generated setter method is retaining your Bar instance as you told it in the @property declaration.

nschmidt
However, despite the difference between getter and field selector mechanisms, there still no functional difference between the mentioned lines. I.e. the same object will receive the same message, right?
Sergey Mikhanov
well, there can be. Since you are free to implement the method bar in any way you want. For instance, you could return a proxy object or what ever. Even in case you synthesize the accessor methods, they can behave differently, like synchronizing access if you set the property to be atomic.
nschmidt
But in the case when I synthesize the property, even if there would be synchronization, or retaining, or whatever else, there still no functional difference between the mentioned lines, in the sense that *same object* receives *same message*, right?
Sergey Mikhanov
There is definitely a difference. A derived class could override -(Bar*)bar and return another object.
Nikolai Ruhe