Reputation: 5801
I was reading the posts about prefixing underscores infront of instance variables in Objective C. Especially the following posts,
Prefixing property names with an underscore in Objective C
How does an underscore in front of a variable in a cocoa objective-c class work?
As I understand when we are using underscores we are directly accessing the ivar instead of using accessors. How this would affect for properties that should be declared as "copy" instead of "Strong". Especially for blocks.
Will I fall in to the trouble using this convention?
Upvotes: 0
Views: 503
Reputation: 6393
One place you do want to use the instance variable is if you override any setter methods, i. e.:
- (void)setFoo:(MyFooInstance *)fooInstance{
_foo = fooInstance;
}
Otherwise you'll create a neat little infinite loop...
Upvotes: 0
Reputation: 47759
When you use an underscore as a part of a variable name you are accessing a variable whose name contains an underscore -- it's (almost) that simple. On top of that there are conventions for naming variables and those (depending on whose) sometimes include naming instance variables corresponding to properties with a leading underscore.
But there's nothing magical about the underscore -- it doesn't, by itself, invoke any special functionality. It's only the conventions (which may or may not be in place in a given piece of code) which cause underscore to have any additional significance.
Upvotes: 0
Reputation: 52632
As nhgrif says, you should be using the accessors (in most cases). The reason why you should add an underscore to the beginning of the instance variables is that by doing so, you make sure that any access to an instance variable stands out in your source code. For example if you have these three lines in a method:
self.myInstance = 0;
myInstance = 0;
_myInstance = 0;
self.myInstance = 0 is clear because of the "self.": You are calling the property setter. _myInstance = 0 is also clear because of the underscore: You are assigning directly to the instance variable. Whether that is good or bad depends on the circumstances, but reading this code I know what you are doing, and I know that it is intentional.
If your instance variable doesn't start with an underscore, you could write myInstance = 0. I might suspect that it assigns to the instance variable directly, but only after reading your code carefully. You might have a global variable named myInstance somewhere. Or a parameter or local variable in your method (lots of questions on stackoverflow where code doesn't work because of this; someone intends to set a property but changes a local variable), or you might have intended to use the accessor but forgot the "self." and thought it's Ok because it compiles.
So the "underscore" convention makes clear to everyone what your code does and what you intended it to do. So you should use the underscore, but you should rarely use instance variables.
If you are using ARC, reference counting will work correctly if you use instance variables directly, but "copy" semantics will not work. So assigning a block directly to an instance variable is a pretty bad idea (unless you copied it by hand). Without ARC, you'd also have to do reference counting (retain/release) by hand. Most importantly, you can observe a property (have code that is automatically called if someone changes a property), and that doesn't work at all if you access instance variables directly.
Upvotes: 2
Reputation: 62072
You SHOULD be using the accessors you created when you declared the property. If you don't need the accessors, then you shouldn't be creating a property, but instead simply an ivar.
With that said, assuming you didn't write custom accessors, accessing the ivar directly is virtually the same as going through the accessor. It does not matter how the property is declared.
Upvotes: 0