Search code examples
iphoneobjective-ciosself

When to access property with self and when not to?


Can anyone explain the difference between setting someObject = someOtherObject; and self.someObject = someOtherObject; if someObject is a class property created with @property (nonatomic, retain) SomeType someObject;

To clarify I have something like:

@interface SomeClass : NSObject {
   SomeType* someObject;
}

@property (nonatomic, retain) SomeType* someObject;

@end

I have noticed I get EXC_BAD ACCESS sometimes when I use the property without self and it seems quite random. When I use self my program acts as it should be. I don’t get any compiler errors or warnings when I skip self so I guess it is somehow valid syntax?


Solution

  • Properties are just a convenient way to access the data. So when you are declaring the property @property (nonatomic, retain) SomeType* someObject; this means that during access there would be synthesized 2 methods:

    getter:

    -(SomeType*) someObject {
       return someObject;
    }
    

    setter

    -(void) setSomeObject:(SomeType*) obj {
       [someObject release];
       someObject = [obj retain];
    }
    

    So the main difference between properties and ivars is that properties dynamically creating the setter/getter methods (and you can override them). But when you're writing someObject = new_val, you're just copying the reference to the memory location. No additional work is done there except one assembly instruction.

    There is one more thing to mention: atomic and nonatomic. With atomic, the synthesized setter/getter will ensure that a whole value is always returned from the getter or set by the setter, regardless of setter activity on any other thread. That is, if thread A is in the middle of the getter while thread B calls the setter, an actual viable value -- an autoreleased object, most likely -- will be returned to the caller in A.

    In nonatomic, no such guarantees are made. Thus, nonatomic is considerably faster than atomic.

    Edit: so if you have some variable, that is accessed from different threads or/and some additional work has to be done (e.g. retain, raise some flags ...), then your choice is property. But sometimes you have a variable, that is accessed very often and access via property can lead to a big overhead, because processor has to perform much more operations to synthesize and call method.