Proper use of variable names - objective-c

This is a purely theoretical question:
I have a class that has a variable: varX.
I have a method that changes this variable. Xcode, with autocompletion suggest:
-(void)setVarX:(float)varX;
In implementation, when I write the instance method, Xcode tells me a warning:
"Local declaration of 'varX' Hides instance variable"
the method:
-(void)setVarX:(float)varX {
varX = varX;
}
So, to solve, I used the underscore in synthesize;
#synthesize varX = _varX;
and the method is:
-(void)setVarX:(float)varX {
_varX = varX;
}
is proper to use the underscore before variables in this way? otherwise how do I use the name of the method suggested by Xcode?
thanks

Using _varX is the right approach. If you leave out the #synthesize line (as of Xcode 4.4) it will automatically generate an instance variable with that name.

Xcode 4.4 (and later) have automatic synthesis of properties (so that #synthesize is not needed anymore) when you don't use #dynamic. The automatic synthesis uses the underscore, so it seems that Apple wants this to be a convention.
First, I disliked this idea, but now I see why it's handy. Those variable names of those properties aren't "reserved" anymore in more methods (I never use underscores in other situations).

Note that changing the instance variable name effectively changes the class, while changing the method argument name does not.
Therefore I prefer to do it the other way around:
-(void)setVarX:(float)_varX {
varX = _varX;
}
so that the instance variable name, which is part of the class externally visible interface, does not need to be changed.

Related

Is it OK to have a method's variable with the same name as a declared property?

I understand this is probably bad practice, but I was just curious as to whether or not this has any negative side-effects, in Objective-C (trying to learn as much as I can):
#interface MyClass ()
// Declare a string called 'foo'
#property (nonatomic, strong) NSString *foo
#end
#implementation MyClass
...
- (void)modifyFoo {
// Create a local variable with the same name as a property
NSString *foo = #"Hello!" // No compiler warnings?
self.foo = foo; // <---- Is this OK?
}
This will not throw up a warning in the compiler, and sure enough, my code works as normal. If there are zero negative side-effects, does the type of property, e.g. weak/strong/assign, etc, have an influence on whether or not this is OK?
Note: I am aware that this will not work when the property is synthesised.
This is fine and is my personally preferred approach. The reason no compiler warning is generated is that the instance variable is actually named _foo. This is done by the auto-synthesise added by the compiler (it generates #synthesize foo = _foo for you). Maintaining naming consistency aids clarity.
The main potential side effect is that you inadvertently add / fail to add self. and end up trying to message nil.
Firstly:
this will not work when the property is synthesised.
Huh? Why not?
Actually, it's "OK" in the sense that it works. Actually, there's no ambiguity when you use the self keyword and the dot notation to access your property. If, however, you had an instance variable with the same name as your local variable, then the object with a narrower scope (the local variable in this case) hides the one with a wider scope (the ivar). And that may be undesirable. As far as I know, it even results in a compiler warning. Furthermore, it's hard to get it wrong and decreases overall code readability, so don't do this if you have that identically named instance variable.
If I recall correctly, recent versions of the clang/LLVM toolchain automatically synthesize properties for you, and the name of the backing ivar for a property is preceded by a leading underscore, so this should not be a problem.

Does the name of an argument matter when defining a function?

Does it matter if I define a function with one argument name in the .h file, for example...
-(foo *) initWithId:(NSString *)id;
And then in my implementation give the argument a different name because it hides a class property:
-(foo *) initWithID:(NSString *)idString;
I know that the autocomplete files use .h as the 'basis' for their autocomplete fillers, and while it doesn't apply to this scenario, I prefer to use the property name in my functions to remain as consistent in my coding style as possible. It makes more sense to understand that getFoo and setFoo both apply to the same property 'foo' as in -(bar *) initWithFoo:(id) foo;.
As far as I can tell, the compiler doesn't have any issues with it, but somehow it seems like it SHOULD matter.
The LLVM analyzer in Xcode does seem to care about some things like methods starting with new and copy.
Here's a sample warning when I name a property starting with new:
"Property's synthesized getter follows Cocoa naming convention for
returning 'owned' objects"
(the #property had a #synthesize that created a getter method starting with new).
No, the compiler doesn't care. Other people who read your code might care.
the only time it really matters is if you have an instance variable name with the same name.
#synthesize something;
- (void)methodForSomething:(id)something
{
something = something;
}
this will throw an error. obviously the solution is to modify your instance variables naming.
#synthesize something = _something;
other then that, parameter names dont matter.

(Objective C) what is the advantage of doing #synthesize myvar = _myvar (if any)? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
It is not fully clear to me (other than for readability of the code), why you wanna create an internal variable with an underscore prefix when you create the property.
Since everything is handled internally, why bother to do so, since we do not add any code to the getter and setter?
And even if i gotta add some code to the getter or setter, i do not see why i cannot just do the check on myvar instead than having to check _myvar and then assign it to myvar.
Can anyone give me some explanation, other than "do it because that's what everyone does ?" I would like to understand the whole reason behind this practice (that seems to be pretty common even if there is no custom code for the getter and setter).
Thanks!
I've wondered this many times myself. Interested in other people's answer, but one reason I've found is that it forces you to notice if you're accessing the ivar directly when you should be using the getter/setter.
self.myvar = #"blah"; and _myvar = #"blah";
vs
self.myvar = #"blah"; and myvar = #"blah";
It's easy to leave the self. out by accident... it's a lot harder to put the _ in by accident.
An Objective-C property usually has a backing instance variable (I guess you know the difference between a property and an instance variable).
The property may have a different name than the instance variable.
For instance, you may have an instance variable named x, with a property named y.
You can synthesize the y property to the x variable using:
#synthesize y = x;
Now about the underscore.
It's a common practice to use an underscore prefix for instance variables, to prevent naming collisions, or compiler warnings (shadowed variable), when having for instance a method argument with the same name as an instance variable.
The underscore prefix also makes clear that you are referring to an instance variable.
By using the underscore prefix for instance variables, you're free to use the name without the underscore in method's arguments, stack variables, etc.
But when using a property, you usually don't want the user to write an underscore.
So you usually have an x property for an _x instance variable.
This is why you write:
#synthesize x = _x;
Let's take an example:
#interface Test: NSObject
{
int x;
}
#property( readonly ) int x;
#end
This is quite common... But now imagine this in the implementation:
- ( id )initWithX: ( int )x
{}
We have are a naming collision.
Inside our method, x will refer to the method's argument. And there is no pretty way to access the x instance variable.
Depending on your compiler's warning flags, this may also generate a warning (-Wshadow).
If you use an underscore prefix for your instance variable, everything is just simple:
- ( id )initWithX: ( int )x
{
if( ( self = [ super init ] ) )
{
_x = x;
}
return self;
}
No conflict, no naming collision, improved reading... Just a nice way...
When using a property of self, it's easy to forget the "self":
[self.field doSomething]; // what you probably want
[self setField:someObject]; // also kosher
self.field = someObject; // ditto, although not my style
vs.
[field doSomething] // might work.. but will bite you eventually
field = someObject; // almost certainly wrong anywhere outside a custom setter
If the property and the ivar are named identically, the latter cases will compile without complaint and appear to work... until they don't, and you get a weird hard-to-reproduce edge case bug.
If the ivar has a slightly different name, say with a trailing _ appended, the compiler will stop you and make you explicitly decide: do I want to refer to the property here, or the ivar directly?
(All that said, I am lazy and often do #synthesize field;, and replace it later with #synthesize field = field_; when I actually need the distinct ivar, say when it's custom-setter-writing time.)

what #synthesize variable = _variable will do?

I have seen code like that in the Application delegate in iPhone project for example.
what is the variable with the underscore means? can I use it as setter and getter for the variable?
also when releasing the variable should I use:
[variable release];
or
[_variable release];
Thanks.
In some coding conventions the underscore before instance variables is used to be able to quickly differentiate them from other variables. It also helps avoid naming conflicts with local variables in methods and subclass methods.
#synthesize variable = _variable
Creates a setter and getter that set/get the variable you set it to in this case _variable. So outside access uses code like object.variable which is really just returning _variable. however the class usually uses the _variable internally.
#synthesize variable = _variable;
The property name is "variable" and the instance variable that backs it up is named "_variable". You should use the accessors -variable and -setVariable: rather than accessing the ivar directly, except in -init and -dealloc, where you'd use _variable.
In your example variable is a property and _variable is an instance variable. For simplicity sake we can say that by synthesizing you are essentially instructing that the property ( in our case variable) will use the instance variable ( in our case _variable) for storing and retrieving values. What you are really doing is instructing the compiler to create implementations that match the specification given in the property declaration.
The suggested way of releasing when you are using a property will be to just assign it nil. This would essentially release the object and also set the instance variable to nil instead of being a dangling pointer.
If you were not using property then you can call the release on the instance variable and then ideally you want to set it to nil.

self.variable and variable difference [duplicate]

This question already has answers here:
Difference between self.var and simply var
(3 answers)
Closed 8 years ago.
What is the difference between self.myVariable = obj; and myVariable = obj;, when I use #propery/#synthesize to create `myVariable?
It's important to note that dot-syntax is converted to a simple objc_msgSend call by the compiler: that is to say that underneath it acts exactly like a message send to the accessor for that variable. As such, all three of the following are equivalent:
self.myVariable = obj;
[self setMyVariable:obj];
objc_msgSend(self, #selector(setMyVariable:), obj);
Of course, this means that using dot-syntax actually results in a full message send, meaning calling a new function and all the overhead that is associated with it. In contrast, using simple assignment (myVariable = obj;) incurs none of this overhead, but of course it can only be used within the instance methods of the class in question.
The #synthesize directive tells the compiler to generate accessors for your member variables, according to the specifications given in the #property directive in your .h file. (I.e., if you specify retain, the setter will retain the variable, and if you specify copy, it will copy it.)
The accessors will (unless you specify otherwise) be named propertyName and setPropertyName.
Using the . notation (note, not the self syntax as stated above) is saying that you want to use the accessors (a good thing if you are setting strings, and want to ensure the retain count is correct, for example).
So, within your class implementation:
self.bill = fred will call the
accessor setBill.
bill = fred will set bill to fred
directly, without going through the
accessor.
One of the differences I found out when starting Cocoa development is if I set variable to use a #Property/#Synthesize syntax and I didn't use self.myVariable = obj or [self setMyVariable:obj] but instead myVariable = obj, the object is not retained if obj is released later. (Assuming #Property was set up to use retain.)
The reason is the retain count is not set when using myVariable = obj and when the obj is released the count is now zero. (Unless you retain it yourself) But by using the accessor it will do the retain count for you. (Again assuming you set it up to use retain when it was declared).
Shyne
If I can add one important note to this. The answer above are all awesome, so I won't add to the technical side. But just this:
If you create a synthesized property
#synthesize myProp;
Always use the self.myProp pattern to set it.
self.myProp = newVal;
This seems really obvious, but it's important. It's true that there is simply no reason to do this, but until you really understand how the synthesized setters are created you just want to assume you HAVE to use the self. pattern to set the value.
Honest: this will save you a lot of late night debug sessions. Non-retained memory access violations are simply the worst to debug.
The self syntax uses the accessor method, the other syntax does not. This might be a big difference if the accessor does something more than simply assign the new value. See the Declared Properties part of the Objective-C tutorial.
The other answers are correct, the difference is that the dot notation causes the ivar to be changed through the accessory rather than directly.
Until you know what you're doing, I recommend you use the dot notation (i.e. self.propertyName = ...). Cocoa/Obj-C does a lot with key-value coding, and while the phone SDK doesn't take full advantage of that (with things like bindings), eventually it will. Getting used to using the accessors now will save you a lot of headaches in the future.
Using the accessor methods also give you the opportunity to override them and provide more functionality should you need to. By simply changing the value of the ivar, you rob yourself of this capability.