iOS: Usage of self and underscore(_) with variable

Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?

I have been very confused with using self or underscore with variable name after synthesizing it like below:

In .h file:
@property(nonatomic, strong) NSMutableArray *users;

In .m file:
@synthesize users = _users;

Based on my understandings when I use self.users, OS will make sure to release previously allocated memory in set method so we don’t need to take care explicitly.

_users is an instance variable for users and should be normally used while accessing the users variable. If I use _users to change it’s value then it won’t fire KVO delegate which will not notify a class observing users value change.

Moreover, self.users allows differentiating dummy variable in the method name like below,

- (void)assignUsers:(NSMutableArray*)users {
      self.users = users;
}

Could someone please tell me if there is anything that I understood wrong or missing while using _users or self.users. Thanks.

3 Solutions Collect From Internet About “iOS: Usage of self and underscore(_) with variable”

I think it helps to consider how properties are (or might be) implemented by the compiler.

When you write self.users = array; the compiler translates this to [self setUsers:array];
When you write array = self.users; the compiler translates this to array = [self users];

@synthesize adds an ivar to your object (unless you added it yourself), and implements the -users and -setUsers: accessor methods for you (unless you provide your own)

If you’re using ARC, -setUsers: will look something like:

- (void)setUsers:(NSArray *)users
{
    _users = users; // ARC takes care of retaining and release the _users ivar
}

If you’re using MRC (i.e. ARC is not enabled), -setUsers: will look something like*:

- (void)setUsers:(NSArray *)users
{
    [users retain];
    [_users release];
    _users = users;
}

* – Note that this is a simplified, nonatomic implementation of -setUsers:

when you are using the self.users, you access the property via the setter or getter.

when you are using the _users, you access the property directly skip the setter or getter.


here is a good demonstration of it:

- (void)setUsers:(id)users {
    self.users = users; // WRONG : it causes infinite loop (and crash), because inside the setter you are trying to reach the property via setter
}

and

- (void)setUsers:(id)users {
    _users = users; // GOOD : set your property correctly
}

this is the point in the case of the getter as well.


about the basic memory management (in case of MRR or ARC): the iOS will dealloc the object if there is no more strong pointer which keeps it alive, no matter how you release the pointer of the objects.

Yes, that’s pretty much correct. A couple of minor points:

iOS doesn’t automatically release an object just because you use dot notation. It releases an object when the property is declared as copy or retain (or strong in ARC). If, for example, you are using non-ARC code and the property is declared as assign, it won’t release the object.

With the latest version of the developer toolchain (Xcode 4.4+), you no longer have to manually synthesise properties – they are automatically synthesised (with the leading underscore).