Thursday, May 23, 2013

Underscore before property name



_variableName vs self.variableName


I was asked today what is the difference between using underscore before property name and without underscore.


My student came with example:


“I have property with int type and I want to write setter. I can do it this way (Code Listing  1)  but when I will to it other way (Code Listing 2) the app always crashes.”



Code Listing 1- Example A



@property (nonatomic) int count;
- (void)setCount:(int)count
{
   _count = count;
}



Code Listing 2- Example B


@property (nonatomic) int count;
- (void)setCount:(int)count
{
   self.count = count;
}




So what is diffrence between them? Let’s think...

Notation is different... so is this working same in both cases? Is property with underscore prefix different than the other?

In most cases the result is same 

(not in Example 2)

, but the way how it work is completely different.
What is really happening in Example A and what in Example B?

In example A there is no direct assignment. Instead of assigning value the setter (method) is invoked. It work same as we would use setter as method or Key Value Coding (KVC). So the syntax of
self.count = count;
is equivalent of
[self setCount:count];
or
[self setValue:count forKey:@”count”]; //(KVC)

So … any ideas why Example B is crushing App on runtime?
“setCount” is setter for variable count. According to definition “self.count = “ is calling setter - “setCount” - so it starts calling itself recursively... endlessly.

And uderscore... syntax with uderscore is bypassing setter (or getter) method and allows accessing value directly. This is reason why we have to use it in our getter or setter. (Example A).

If this is still unlear try to implement Example 3 into your project. You can make a cusotm setter.  

Code Listing 3- Example C


@property (nonatomic) int count;
- (void)setCount:(int)count
{
   _count = count + 100;
}



Now try two types of calling.
self.count = 10;
and
_count = 10;

After first call count should have value of 110 and after second 10.

Hope you find this usefull.

3 comments: