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

10,611

Solution 1

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:

Solution 2

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.

Solution 3

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).

Share:
10,611
Paresh Masani
Author by

Paresh Masani

Updated on June 08, 2022

Comments

  • Paresh Masani
    Paresh Masani almost 2 years

    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 its 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?

    • Paresh Masani
      Paresh Masani over 11 years
      Hi @qegal I went through that thread and if you read my question, most of points are the conclusion points but what I couldn't get is when to use what!
  • Paresh Masani
    Paresh Masani over 11 years
    Thanks Jim. I tried Xcode 4.4 with iOS 6 and yes it doesn't require synthesising properties but would that App work on lower version of iOS?
  • Lomithrani
    Lomithrani over 11 years
    Yes - from the official documentation: The default @synthesize feature requires no special SDK or runtime support. Questions like that, you should read the documentation.
  • holex
    holex over 9 years
    dear Down-voters! I would have been honoured to get some feedback about why your hands were shaking above the down-voter button, because – you believed or not – I'm not a mind reader to figure out it. thank you!
  • holex
    holex almost 8 years
    I'm not sure at all how you meant that: "You show an abuse of self and ...", could you elaborate please? the good demonstration is showing the difference between bypassing and calling the same setter inside the setter, which'd cause infinite recursive loop and it crashes when the stack is overflowed – therefore the final approach is avoiding causing infinite loops in runtime.
  • Ash
    Ash about 7 years
    The only answer on this topic that talks about the difference from a reference counting perspective with such elegance. Excellent.