Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS, using underscore vs using iVar directly [closed]

This has been asked a lot, but this question is to get examples of when you would use each of these methods. Please use examples other than the setter and getter infinite loop

example.

.h -
@property(nonatomic, strong)NSMutableArray* mutArray
.m -
@synthesize mutArray= _mutArray;

1) would I want:
_mutArray = [[NSMutableArray alloc] init];
OR
self.mutArray=[[NSMutableArray alloc] init];
Why would I do each of them, and what is the difference?!

2) If I want to add an object to it...
[_mutArray addObject:object];
OR
[self.mutArray addobject:object];

and why?!

Thanks so much!

like image 783
jgvb Avatar asked Mar 26 '13 18:03

jgvb


1 Answers

You should only deal with your ivars in init and dealloc or where absolutely required by an implementation detail (such as inside of the accessor itself, or where you actually require a memory address). Other than in those places, you should always use the accessor, which means [self foo] rather than _foo.

self.foo is just syntactic sugar around the actual call, which is [self foo]. It is important to understand that self.foo is a standard ObjC message-send, and means exactly the same thing as [self foo]. By convention, you should only use dot-syntax when referring to properties.

Pre-ARC, direct use of ivars was the #1 cause of crashes in my experience. The likelihood of you screwing up when assigning directly to an ivar without ARC quickly approaches 100% over the scope of the program.

Since ARC, I still argue that you should always use accessors (with the exceptions given above), but the reasons are more subtle. The main reason for it is that an accessor may be customized, either in the current class, in a subclass, or via KVO (which happens outside your code entirely). If you directly access the ivar, then you will bypass this. For example, say the property is lazily-created (which is pretty common). Then if you use the ivar before it's created, you'll get subtle bugs. So you have to remember, for that property, to always use the accessor. Similarly, you might call setNeedsDisplay or post a notification, or the like.

If you have a simple rule that says "I will always use accessors" then it's easy to look at the code and know it's right. In the few cases you need to circumvent the accessor, the _ says "hey, pay attention here, I'm doing something weird."

If you have a rule "I will use accessors for properties that need it, but not for ones that don't" then it's almost impossible to look at the code and know whether it's correct. Did the previous developer use the ivar because it was required or just because he felt like it? Can you change it or not? It's very hard to know.

So even post-ARC, using accessors consistently is good defensive programming and I highly recommend it.

like image 159
Rob Napier Avatar answered Sep 28 '22 05:09

Rob Napier