I've recently discovered that there is no need to declare a getter as a property to use the dot notation. I don't know about other compiler versions, but this is true for Apple LLVM 3.1. Does anyone foresees any problems with it? So, basically:
---------Star.h----------
-(UInt32)age;
---------Star.m----------
-(UInt32)age
{
//get star age
return starAge;
}
---------RootViewController.m----------
{
...
//use this instead of [star age] even if there is no synthesized property "age"
NSLog(#"%i", star.age);
...
}
Your code is perfectly acceptable. A compiler wold do something similiar if you wrote:
---------Star.h----------
#property (readonly) UInt32 age;
---------Star.m----------
#synthesize age = starAge;
Your code is fine. Dot notation is just another way to invoke an instance method.
self.foo = bar; is the same as [self setFoo:bar];
bar = self.foo; is the same as bar = [self foo];
What does ARC make of that?
What happens if you try to compile :
- (void)setX:(NSInteger)x {
NSLog(#"New x is %i", x);
}
...
[self setX:100];
without declaring X as a property?
Even if it works I feel that it's good practice to add that simple extra line of code to declare it as a property even if all it does is make your code more readable.
Related
I have set up one of my core data attributes as a Boolean. Now, I need to set it, but XCode keeps telling me that it may not respond to setUseGPS.
[ride setUseGPS: useGPS.on];
What is the method for setting a boolean in core data? All my other attributes are set this way, and they work great. So, not sure why a boolean does not work to be set this way?
Core Data "does not have" a Boolean type (it does, but it is an NSNumber).
So to set the equivalent of useGPS = YES.
[entity setUseGPS:[NSNumber numberWithBool:YES]];
And the other way around:
BOOL isGPSOn = [[entity useGPS] boolValue];
Update:
As pointed out by SKG, With literals in Objetive-C you can now do it in a simpler way:
[entity setUseGPS:#YES];
BOOL isGPSOn = entity.useGPS.boolValue;
As an alternative approach to the accepted answer, you can simply change the typing from an NSNumber* to a BOOL in the managed object interface definition, such as:
#property (nonatomic) BOOL useGPS; // Notice that the 'retain' is also removed as we're now dealing with a scalar rather than an NSObject
Various alternative approaches are discussed here, but Chris Hanson's response was most illuminating for me, especially:
If you have a numeric attribute
(including a boolean attribute) that's
required, you can just type it as a
scalar instead, and Core Data will do
the right thing:
#property (nonatomic) BOOL isDone;
Even if the attribute is optional,
that'll still work - it'll just
conflate "not present" with "false."
and for a more aligned Cocoa implementation:
One other thing you might want to do
is name the property "done" and just
specify the getter as "isDone." That's
the usual Cocoa naming convention:
#property (nonatomic, getter=isDone)
BOOL done;
Then you can write "if (item.done) {
... }" or "item.done = NO;" and the
compiler will still generate -isDone
for accesses of the property.
Thanks Chris, and hope that this helps someone.
Just to complement #RickiG answer, the way to create a NSNumber from a Booland vice-versa in Swift (at least since v4.2) is:
let nsNumberFromBool = NSNumber(booleanLiteral: true) // or false
let boolFromNSNumber = nsNumberFromBool.boolValue
The "fix" for this (IMHO, it's a bug in Apple's SDK) is to add the following code to your CoreData-generated class. NB: if you do this in a category, in a separate file, then you don't have to re-copy/paste it each time you regenerate the CoreData classes inside Xcode
- (BOOL)useGPS
{
[self willAccessValueForKey:#"useGPS"];
BOOL myuseGPS = [[self primitiveUseGPS] boolValue];
[self didAccessValueForKey:#"useGPS"];
return myuseGPS;
}
- (void)setUseGPS:(BOOL)newValue
{
[self willChangeValueForKey:#"useGPS"];
[self setPrimitiveUseGPS:[NSNumber numberWithBool:newValue]];
[self didChangeValueForKey:#"useGPS"];
}
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?
I've noticed that in a lot of the reference materials out there, I see that a lot of the time, variables are named _variable in the .h file, then are #synthesize'd in the .m file as
#synthesize variable = _variable;
Why is this done? What am I missing?
Thanks!
There is not consensus on this. Some people like to use it for clarity to separate out class variables, and as another responder noted to avoid conflict with incoming parameter names. Even in Apple sample code the use is mixed.
However, I greatly prefer to not use the _ prefix and have two strong reasons:
1) Some people think the _ is a good indicator of "private". My take is that NO class local variable should be accessed without a setter/getter (property) and thus they are ALL private - given that why not name them in a way easier to read and use autocomplete on? Any overlap in names from parameters is quickly revealed by the compiler, and avoided through more thoughtful naming of parameters (or internal variables).
2) (even better reason) - if you use "refactor" in XCode on an internal class var that is named the same as the property used to access it, the property and synthesize statement will also be renamed. If you use refactor on a class variable prefixed with an _, the property name will not be changed - just the synthesize mapping to the internal name. I pretty much never want the name to vary from the property to the real variable it exposes access to. That alone makes me never want to use _ as a variable prefix, since being able to shift names is just about the most useful thing you can do to improve code clarity.
Using that syntax is an option to make it more clear that the ivar and property are different things.
To code external to the class, there is no difference since it uses the property.
For code in the implementation of the class itself, it can make it more clear when the ivar is used versus the property.
For example, say we have an ivar/property for an NSNumber object:
#interface MyClass : NSObject {
NSNumber *num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
#end
and now using a different name for the ivar and property:
#interface MyClass : NSObject {
NSNumber *i_num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
#end
Previous answers are missing the history behind this. Before Objective-C 2.0, there were no properties. So you’d have an object with instance variables like this:
#interface MyObject: NSObject {
NSArray *myArray;
}
#end
But how would you access them from other objects? the solution was to make setters and getters. But to avoid confusion, they would do it like this:
#interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
#end
The _ serves to clear up confusion between the instance variable _myArray and the method -myArray.
Sometimes people use mVarName (C++) and in Obj-c the style seems to be _varName.
One problem you can have, is imagine that your argument to a function is ...set:(int) x - BUT - you have an iVar called x...well your going to get the compiler crying about stuff like that - not to mention its confusing.
The m,_, whatever helps to show what are member properties of the class.
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
This is purely convention. I suppose its common because when you make a method getter call like this:
[myObject variable]
you are actually calling a method, not accessing a variable directly. the _ in front makes it clear that you are talking about a variable. Personally, I find this syntax annoying and distracting. I find it unnecessary, but you are right, it does appear here and there.
I prefer not to use the '_' prefix because Apple does use it consistently. By avoiding the prefix I then have greater confidence that my ivars do not collide with Apple's when I extend a cocoa touch class. Since we do not have access to the base class' source this is really the only way I know of to avoid accidental reuse of existing private ivars.
Much like
Method names beginning with “_”, a single underscore character, are reserved for use by Apple.
My preference, following Google, is simply to append an underscore and explicitly synthesize (even if I'm reimplementing):
#synthesize varName=varName_;
If I see that trailing underscore outside of init..., dealloc or an accessor, I know something's fishy.
I am having a really odd problem trying to set a simple float value to 1.
My property:
{
float direction;
}
#property(nonatomic)float direction;
Which is synthesized:
#synthesize direction;
I then used the following code:
- (void)setDirection:(float)_direction {
NSLog(#"Setter called with value of %f",_direction);
self->direction = _direction;
}
For testing purposes...
When I try to change the value with this,
[[w getCharacter] setDirection:1.0f];
where [w getCharacter] gives this:
return [[[self scene] gameLayer] player];
I get the warning, "setDirection not defined."
If I switch to dot notation([w getCharacter].direction), I get "confused by earlier errors, bailing out".
Here is where the weirdness starts. When I try to change the value, the debug message displays _direction = 0.00000. When I check the number later, its still 0.000. I am clearly trying to change it to 1, why is this not working?
The simplest explanation is that [w getCharacter] doesn't return the class of object you think it does. Only the class that has direction defined for it can respond to the message. You should test this by explicitly calling it with the class it defined for.
It is possible you did not include the header that defines the method.
Two probably unrelated issues:
The self->direction construction will work for a scalar value but it does an end run around the entire class concept. In this case just use: 'direction=_direction;` and it will set it directly.
Apple reserves all names that start with underscores for its own internal use. You should not use them because Objective-c has a global name space. It's possible that you can accidentally use an Apple variable that is defined deep within a framework. (This is why framework constants all start with NS,CF,CA etc.)
[Note: In the Comments, the author says to ignore this answer.
self.direction = 1; is syntactic sugar for
[self setDirection: 1];
when you call
-(void)setDirection:(float)_newDirection {
self.direction = _newDirection;
}
You seem to be telling the compiler or preprocessor to set up a recursive loop for you. The preprocessor (I think) changes it to this:
-(void)setDirection:(float)_newDirection {
[self setDirection: _newDirection];
}
If you call it simply
-(void)setDirection:(float)_newDirection {
direction = _newDirection;
}
the assignment should work (it worked for me just now)
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?
I've seen this at Apple, inside UIPickerView.h:
id<UIPickerViewDataSource> _dataSource;
why's that underscore there? Does it have a special meaning? A Convention I must know about?
A lot of people use this for private variables, to differentiate between private variables and public variables within an object.
It is a completely optional way of working.
What you're seeing is the use of underlines to distinguish between instance variables and properties. So a class declaration might be:
#interface Foo {
NSString* _label;
....
}
#property (nonatomic, retain) NSString* label; // notice: no underline
Then in the implementation file you would have:
#synthesize label=_label; // the property is matched with the ivar
Now when inside the implementation, if you want to access the instance variable directly you could just use _label but to go through the property accessor methods (which take care of retain/releases and a bunch of other book-keeping tasks) you would use self.label. From the outside, you would always want to go through the {object}.label property.
The other way is to do without the underline and just use:
NSString* label;
#property (nonatomic, retain) NSString* label;
...
#synthesize label;
It works the same but then it might confuse someone reading the code and trying to keep track of label vs self.label. I personally find the Apple convention (with underlines) a bit easier to read but it's a matter of preference.
As people said already _someVar was used to say that a variable was private. It was a simple matter of convention and doesn't really matter.
One other use, taking a trip in the wayback machine in C a _function() represented a function that wasn't platform portable and __function() represented a function that wasn't compiler portable. So, in the standard C library, you will sometimes see a variable with a _ or __ infront of the name, this is what those functions represent.
It's sometimes used to denote private variables. More generally it just means "this variable is different somehow".
can it be that... (jogging memory)...
i vaguely remember reading an ADC document explaining that apple reserves the usage of underscore-prefixed member variables? and that 3rd party developers are discouraged from using this convention so as to avoid collisions?
|K<
I use underscores to denote that a variable is a member, similar to the 'm' prefix in Hungarian notation (which notation I despise thoroughly, but that's another story). Sure you get colour-coding editors these days, but my opinion is that the prefix makes you think about the variable being a member/instance one before you type it, not just sometime afterwards when it gets colour-coded by your editor.
Generally it's to denote that a variable should not be directly touched by a developer. It's not really a requirement but it's good practice if you can't avoid having a public variable in a class that you don't want messed with.
I choose to use underscores for ivars because I often come across the following situation:
#interface MyClass:NSObject
{
NSUInteger count;
}
#property(nonatomic) NSUInteger count;
-(id) initWithCount(NSUInteger) count;
#end
(...)
#implementation MyClass
#synthesize count;
-(id) initWithCount(NSUInteger) count
{
if((self = [super init])){
self.count = count; // Parameter name collides with ivar name!
}
return self;
}
#end
So I do this:
#interface MyClass:NSObject
{
NSUInteger _count;
}
#property(nonatomic) NSUInteger count;
-(id) initWithCount(NSUInteger) count;
#end
(...)
#implementation MyClass
#synthesize count = _count;
-(id) initWithCount(NSUInteger) count
{
if((self = [super init])){
_count = count; // No name collision
}
return self;
}
#end
Of course, I could alternatively change the parameter name to "newCount" or "aCount" (I hate that one). I think it's a matter of taste.
It's a month ago I was reading a line about that. I am not sure, but I think that if I call self.myInstanceVariable then it uses automatically getters/setters, but if I would call directly myInstanceVariable = #"Foo" for example, then I would bypass any getter/setter which would be really, really, reeeaaallly bad. Right/wrong?
EDIT: I tried this in XCode.
The implementation looks like this:
#implementation Test
#synthesize name;
+ (Test*)testWithName:(NSString*)name {
Test* test = [self alloc];
test.name = name;
return [test autorelease];
}
- (void)setName:(NSString*)newName {
NSLog(#"SETTER CALLED!!");
if(name != newName) {
[name release];
name = [newName retain];
}
}
- (NSString*)name {
NSLog(#"GETTER CALLED!!");
return name;
}
- (void)doWrongThing {
NSString *x = name;
NSLog(#"doWrongThing: %#", x);
}
- (void)doRightThing {
NSString *x = self.name;
NSLog(#"doRightThing: %#", x);
}
The test code looks like that:
Test *t = [Test testWithName:#"Swanzus Longus"];
//NSLog(#"%#", t.name);
[t doWrongThing];
[t doWrongThing];
[t doWrongThing];
[t doRightThing];
So after launching this code in another method (I just used an existing project ;) ), I received this output in the console:
2009-05-01 19:00:13.435 Demo[5909:20b] SETTER CALLED!!
2009-05-01 20:19:37.948 Demo[6167:20b] doWrongThing: Swanzus Longus
2009-05-01 20:19:37.949 Demo[6167:20b] doWrongThing: Swanzus Longus
2009-05-01 20:19:37.949 Demo[6167:20b] doWrongThing: Swanzus Longus
2009-05-01 20:19:37.950 Demo[6167:20b] GETTER CALLED!!
2009-05-01 20:19:37.965 Demo[6167:20b] doRightThing: Swanzus Longus
Like you see, you MUST use self.instanceVariableName in order to use the getters and setters (or you do the call in brackets, works too).
Confusion Alert: You must only use self if you hack around in a method of the object from which you want to access an instance variable. From the outside, when you call someObjectPointer.someInstanceVariable, it will automatically access the getters and setters (yep, I tried that out too).
Just thought someone would be interested in a little case study ;)
That is correct. If you directly use the variable, bypassing the getter/setter you could create bugs. The getter/setter may be responsible for retain and/or releasing the object as well as other things. This could result in crashes/memory leaks etc.
If you are aware that you are bypassing the getter/setter and take the right precautions, there is nothing wrong with accessing the variable directly.
Jesse has some good insight (+1 to you, sir).
The only circumstance under which I would consider explicitly calling the underlying member variable directly (thus bypassing the getter/setter) is when I have written the getter/setter myself, and know exactly what it is and isn't doing, and 99% of those times is when I'm just initializing the member in my constructor.
Just read the documentation
First, this is incorrect
Test* test = [self alloc];
correct is
Test* test = [[self alloc] init];
Second, if you write
#synthesize name;
methods
- (void)setName:(NSString*)newName
- (NSString*)name
will be generated(!! dot-syntax is just syntax-sugar !!) automatically
Third, when you write
myvar.itInstanceVariable
it translates to
[myvar itInstanceVariable]
and
myvar.itInstanceVariable = newValue
translates to
[myvar setItInstanceVariable:newValue]
About your comment, when you declare you property in that way
#property(nonatomic, retain) MyType *myVar;
and write in implementation
#synthesize myVar
it creates two methods
- (MyType*)myVar {
return myVar;
}
- (void)setMyVar:(MyType*)newVar {
if (myVar != newVar) {
[myVar release];
myVar = [newVar retain];
}
}
so you don't need to worry about reteaning/releasing
Yes, the property syntax calls the setter. In almost all cases, this is what you want, since it handles a lot of memory management correctly by default. Also, the property name, ivar name and getter/setter names can also all be different, so you may find cases where it doesn't look like self.myInstanceVar.
Also, just as a side note, you may or may not know this already, but there's no point to synthesizing a property if you're just going to write all the accessor methods anyway.