0

When I was working on a game the other night, I realized that I could increase the performance of my "tick" code by decreasing the the number of method calls by using _myObject instead of self.myObject.

Assuming that myObject is a property, was implicitly synthesized by the compiler, and already has a value, will the bottom one do the same thing as the top one?

// Non-ARC
self.myObject = [self someValue];
_myObject = [self someValue];
Nate Symer
  • 2,185
  • 1
  • 20
  • 27

3 Answers3

5

Those two lines are fundamentally different. The former is essentially a method call to the property's setter method, while the latter is a direct member assignment.

When you do something like self.myObject = x, that's typically the equivalent of method call of the form [self setMyObject:x] (although the actual setter method name can be something else if overridden in the property declaration).

In the case of a retain or copy property, there is obviously a lot more going on in that method than simple assignment. But even in the case of an assign property, there are major differences.

When you have a method call, there is always the possibility that the method could be overriden elsewhere in the code. In the case of a direct assignment, it's always an assignment and nothing else.

With the method call, you automatically have support for Key-Value Observing. With the direct assignment, no KVO notifications will be generated.

And finally, as you've noticed, there is obviously a significant performance difference between a direct member assignment and a call to a setter method.

James Holderness
  • 22,721
  • 2
  • 40
  • 52
  • That's what I was thinking. So for optimal performance, I should access `myObject` through `_myObject` (e.g. calling a method on the object), but I should use the `self.myObject` to set the value? – Nate Symer May 03 '13 at 13:11
  • If performance is the primary concern for you then yes. Just bare in mind that you're losing a certain amount of extensibility and information hiding as a trade-off for that performance gain. – James Holderness May 03 '13 at 14:07
  • As a follow up, I needed to do some high performance code for a music app, and I did end up accessing the objects directly – Nate Symer Jul 18 '13 at 23:33
4

The answer depends on the declaration of the property: for example, if myObject is declared as copy, these two operations are very different: assignment through a property would make a copy, while assigning to variable directly would not copy. If the property is assign and nonatomic, though, the action they perform would be the same.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0
//for @property (noatomic, retain) NSString* myObject, the setter generated by compiler after synthesize will be like this:
- (void) setMyObject: (NSString*) newObj
{
    NSString* temp = [newObj retain];
    [_myObject release];
    _myObject = temp;
}

//for @property (noatomic, copy) NSString* myObject, setter will be like this:
- (void) setMyObject: (NSString*) newObj
{
    NSString* temp = [newObj copy];
    [_myObject release];
    _myObject = temp;
}

//for @propert (noatomic, assign) NSString* myObject, setter will be like this:
- (void) setMyObject : (NSString*) newObj
{
    _myObj = newObj;
}

Hope this helps.

MasterBeta
  • 606
  • 6
  • 15