Sanity check. Given this:
#property (readwrite, nonatomic) NSDate *start;
Then aren't these 2 lines of code identical?
Version 1:
self.start.description
Version 2:
[self.start description]
i.e. start.description calls the description method on the start object.
Yes, they're identical, and so is [[self start] description]
Basically yes.
Around the property there is a setter and getter autosynchoronizsed. In the event that you use an #syncronize statement then you have a chance to influence how the setter, getter and property are named. If you autosynchronize the property's name is _start. The getter name is start and the setter name is setStart.
So
something = self.start
actually calls the getter and
self.start = something
calls the setter.
Equivalents are:
something = [self start];
[self setStart:something];
If you ever want to access the instance variable directly then do so by:
_start = something;
something = _start;
In the event that you just use #synthesize start; then the equivalent would be:
start = something;
something = start;
That may well be confusing but start actually addresses the instance variable while self.start uses the setter/getter. This difference comes to vast importance when you do not ARC. Depending on the property parameters (e.g. assign, copy, retain, ...) the automatically generated getter and setter does some memeory management for you while the memory management is left to you when you work directly with the instance variable.
Yes. The result will be identical in both cases; properties are (mostly) just sugar around accessor methods written in the conventional Cocoa style.
I say "mostly" because there are some minor internal differences. Properties are added as meta-data to the runtime description of the Objective C class. You can, via some reflection, find out a list of properties that have been declared as such. This list is different from a list of methods that are named in the style of getter/setters.
Related
I am trying to understand the methods generated when properties are used.
Say I have the following declaration
#property int myint;
Now I know I could access this variables as such (say d was my instance of the class)
d.myint = 12; //this is equivalent to [d setMyint:12];
NSLog(#"The value is %d",d.myint); // what method is generated ?
What is the getter method called ? I was under the impression it was called getMyint however that isnt available ? Any suggestions if I might be missing something here?
As stated in the other answers, the proerty declaration gives you a getter and a setter for that instance variable for free! The notation is that you can either get [self myInt]; or self.myInt;. Both calls are 100% equivalent, i.e. they will both call the method - (int)myInt. This method is not visible (or rather, it's not explicitly implemented, see below) by default, however, you can implement it to provide some custom logic (e.g. check for specific values, error handling or lazy instantiation). If you want to override it, put this in your .m file.
- (int)myInt {
NSLog(#"getter of my int called, current value %d", _myInt);
return _myInt;
}
I only want to add to the the previous answers that in Objective-C, you have the possibility to rename your getters and setters when declaring the property, like so:
#property (getter=getMyInt) int myInt;
you can call those in the exact same way that you would use your normale getter:
int myInt = [self getMyInt];
// or
int myInt = self.getMyInt; // (will work but is not recommended since the compiler will interpret this as calling the getter of a property named `getMyInt` and only when this one is not found will actually fall back to the custom getter (thx to #NikolaiRuhe again for pointing this out))
Update:
Agreeing with most of what #NikolaiRuhe stated in his comment, here is a clarification of my answer referring to the mentioned issues:
This is indeed a typo, of course the way to use the property getter is by either calling [self myInt] or using dot notation self.myInt, and not [self getMyInt]. These calls are however 100% equivalent since they both invoke the actual getter.
About the visibility, indeed I should have been more explicit here. In OOP terms, visibility is a concept that describes the accessibility of instance variables from the outside of a particular class. I meant it exactly in the way that #NikolaiRuhe suggested, i.e. that this method is not explicitly implemented (so, it's not visible in the code by default). Sorry about this misunderstanding!
I am actually not sure about this point. For me this didn't make much of a difference in the past, I don't insist on this point. So I'd well acknowledge that the act of explicitly implementing a getter is not actually an override but rather a replacement of the synthesized method.
After explicitly renaming the getter to getMyInt like I suggested above, I don't see anything "wrong" with calling self.getMyInt. Why would this be the wrong way to access the property?
The getter method would be:
[d myInt];
Per the Apple docs :
You access or set an object’s properties via accessor methods:
NSString *firstName = [somePerson firstName];
[somePerson setFirstName:#"Johnny"]; By default, these accessor methods are synthesized automatically for you by the compiler, so you
don’t need to do anything other than declare the property using
#property in the class interface.
The synthesized methods follow specific naming conventions:
The method used to access the value (the getter method) has the same
name as the property. The getter method for a property called
firstName will also be called firstName.
The method used to set the value (the setter method) starts with the
word “set” and then uses the capitalized property name. The setter
method for a property called firstName will be called setFirstName:.
The syntax of getter method would be-
-(int)myint{
return myInt;
}
It will return myInt property of the receiver if this message i.e. d in your case.
If you are creating a property in objective-c, it creates 3 things for you.
an instance variable which you can access by using an underscore before the property name. Ex: _myint
a getter method which you can call directly by using the property name. Ex: [self myint]; / self.myint, this will actually call - (int)myint {} method.
a setter method which you can call by using a 'set' keyword before it. Ex: [self setMyint:12]; / self.myint = 12, this will actually call - (void)setMyint:(int)myint {} method.
Source
So when you write d.myint = 12; this is equivalent to writing [d setMyint:12];
And when you write NSLog(#"The value is %d",d.myint); this is equivalent to writing NSLog(#"The value is %d",[d myint]);
Custom Getters and Setters
Credits
You can also give custom names to your property Getters and Setters. This is how it is done
#property (getter=getMyInt, setter=setMyIntWithInt) int myint;
Ex:
[d setMyIntWithInt:12]; //This will set the instance variable to 12.
NSLog(#"The value is %d",[d getMyInt]);
Also, you can override these methods in your implementation(.m) file for error handling or lazy instantiation.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between self.ivar and ivar?
In Objective-C, what's the difference between [self setVariable: newStuff] and variable = newStuff?
When you have a class with a variable
#property (nonatomic) NSInteger num;
and you want to change the variable, typically you can do
[self setNum: newNum]
but you can also do
num = newNum
I know if you declare the variable readOnly, you can't use the first method to change it, but what's the concept behind it? Is it just because the second method with the setter can be called outside of its own class? Like if the class's instance was called 'sample'.
[sample setNum: newNum]
but then if you are changing the variable inside the class, either way is fine?
In Objective-C, what's the difference between [self setVariable:
newStuff] and variable = newStuff?
To be absolutely pedantic, one of them assigns the variable property the value in newStuff, whereas the other one assigns the value of newStuff to the iVar variable, but what I think you had in mind was a comparison between [self setVariable:
newStuff] and self.variable = newStuff. In that case, nothing is different, the compiler will expand case 2 out to case 1.
I know if you declare the variable readOnly, you can't use the first
method to change it, but what's the concept behind it? Is it just
because the second method with the setter can be called outside of its
own class? Like if the class's instance was called 'sample'.
readonly variables are important in cases where certain properties are private to the implementation of a class, but should be visible to other classes.
For example, if I were writing a Stack, I might want to expose the count of the number of items on the stack, but it would be a very bad idea for other classes to be able to write to the count variable. If I weren't smart and were using something like a count variable, I would want to be able to adjust the count of the semaphore internally (meaning you need it to be internally readwrite), so I declare a visibly readonly property so other classes can get it, but declare it internally readwrite so I can modify it:
//.h
#interface CFExampleStack : NSObject
#property (nonatomic, assign, readonly) int count; //readonly
#end
//.m
#interface CFExampleStack ()
#property (nonatomic, assign) int count; //readwrite
#end
Is it just because the second method with the setter can be called outside of its own class?
Well, that depends on how your instance variable is declared. By default, instance variables are #protected, i. e. they can be accessed from within the class and its subclasses only. However, if you explicitly declare an ivar as #public, then you can access it outside the class, using the C struct pointer member operator ->:
obj->publicIvar = 42;
However, this is not recommended, since it violates encapsulation.
Furthermore, if you use a custom setter method, then you have the opportunity to do custom actions when a property of an instance is updated. For example, if one changes the backgroundColor property of a UIView, it needs to redraw itself in addition to assigning the new UIColor object to its appropriate ivar, and for that, a custom setter implementation with side effects is needed.
Additionally, there are retained ("strong") and copied properties in case of instance variables that hold object. While writing a setter for a primitive type such as an integer is as simple as
- (void)setFoo:(int)newFoo
{
_foo = newFoo;
}
then, in contrast, a retained or copied property needs proper memory nanagement calls:
- (void)setBar:(Bar *)newBar
{
if (_bar != newBar) {
[_bar release];
_bar = [newBar retain]; // or copy
}
}
Without such an implementation, no reference counting would take place, so the assigned object could either be prematurely deallocated or leaked.
One more important difference...
Whenever you use self.prop KVC comes into play and you can observe the changes in the object, while _prop bypasses it.
I have this property:
#property (nonatomic, getter = getSolutionsCount, setter = setSolutionsCount:) NSInteger solutionsCount;
and implementation
- (NSInteger)getSolutionsCount {
return self.solutionsCount;
}
and I get EXC_BAD_ACCESS on this method - (NSInteger)getSolutionsCount.
What am I doing wrong here?
dot syntax is basically a shortcut for calling the getter. You have infinite recursion in your getter method.
What you need to do is return the instance variable directly:
- (NSInteger)getSolutionsCount {
//latest xcode makes variables with _property name automatically
return _solutionsCount;
//older versions of xcode or having written #synthesize solutionsCount
//will necessitate
//return solutionsCount;
}
Also just FYI objective-c convention is to have the getter method be defined as just the variable name. A getter which is the same as the property name is assumed if you don't write a getter in the property declaration
EDIT:
also i'm assuming this isnt the whole implementation for your getter because if it is let the compiler make it for you automatically, you don't need to write anything. (or by writing #synthesize propertyName = _propertyName in your implementation block with older versions of xCode)
The line self.solutionsCount is translated to [self getSolutionCount]. You are making a recursive call.
If you simply want to return the synthesized ivar then don't even implement this method. But if you do then simply call return _solutionCount;.
The problem is that self.solutionsCount is identical to [self getSolutionsCount], so your getter is directly recursive. You probably want to access the underlying ivar directly, to do so use self->_solutionsCount. Or, if you prefer not to explicitly use self, simply _solutionsCount.
There are several problems here:
According to the naming convention getters should not start with get. To read the value you need to use self.solutionsCount. Hence, you do not need to specify the name of the getter method in the property declaration.
You do not need to specify the name of the setter for it will be automatically generated.
The property should look like this:
#property (nonatomic, assign) NSInteger solutionsCount;
You do not need to write a custom getter implementation to make it work. Ask the compiler to synthesize the methods for you:
#synthesize solutionsCount;
If you want to have a direct access to the instance variable, ask compiler to sythesize it for you:
#synthesize solutionsCount = _solutionsCount;
Read objective-c and naming convention docs first. They will help enormously.
Good luck!
So, I've already read up on the documentation which notes
Objective-C 2.0’s dot syntax and key-value coding are orthogonal technologies. You can use key-value coding whether or not you use the dot syntax, and you can use the dot syntax whether or not you use KVC. Both, though, make use of a “dot syntax.” In the case of key-value coding, the syntax is used to delimit elements in a key path. It is important to remember that when you access a property using the dot syntax, you invoke the receiver’s standard accessor methods.
It then provided an example that supposedly showed the difference between the two. However, I still don't get, what's the difference between KVC and property accessor methods? Aren't they the same? And how do I distinguish between dots that call setValue:forKeyPath: and simple accessors?
However, I still don't get, what's the difference between KVC and property accessor methods?
KVC is a way to call property accessor methods, or otherwise access a property.
What do I mean by “otherwise access”? For KVC purposes, an instance variable with no accessor methods counts as an informal property. It'll get or set the value of the instance variable directly if no matching accessor pair can be found. (Yes, this is not worth using in modern code. Always declare an #property for anything you intend to access elsewhere, and, inversely, don't use KVC to access anything that isn't a public property.)
Property accessor methods are what KVC will call if they exist (preferred, both by KVC and by every sane programmer, over direct ivar access). An accessor may get or set an instance variable, as synthesized accessors do, or access some other storage.
Accessors are implementation, properties are interface, and KVC is one way to use them.
And how do I distinguish between dots that call setValue:forKeyPath: and simple accessors?
A key path is a string, whereas a property-access expression is an expression. The compiler evaluates a property-access expression and translates it into one or more Objective-C messages, whereas a key path is evaluated by KVC at run time.
So, when you use a key path:
[someObject setValue:theValue forKeyPath:#"foo.bar.baz"];
You know it's a key path because (1) it's a string, as indicated in this case by the string-literal syntax #"…", and (2) you're passing the key-path string to setValue:forKeyPath: for it to evaluate.
Using a key path is using KVC to access the named properties. It will send any relevant accessor messages on your behalf.
When you use a property-access expression:
someObject.foo.bar.baz = theValue;
You know it's a property access expression because you are not identifying the properties with a string. You are accessing them (sending the accessor messages) yourself, in your own code.
There isn't much reason to use KVC in any form; when you know the property at authorship/compile time, it's best to have an #property declared and to access the property yourself, whether with property-access expressions or message expressions ([[[someObject foo] bar] setBaz:theValue]). The time to use KVC is when you don't know what property you want to access until run time, which is pretty rare. It's mainly a building-block technology behind KVO, Cocoa Bindings, parts of Core Animation, etc.
Mostly, you'll only want to access properties yourself.
Key value coding allows you to set and get the value of properties through code using the string name of the property. For example, if I had a property named foo which is of type NSString:
[self setValue:#"mystring" forKey:#"foo"];
// read the value by key
NSString *s = [self valueForKey:#"foo"];
Dot syntax is compile syntax sugar. As a personal preference (as some don't agree - fine) I don't use dot syntax but I still use KVC:
[myObj setFoo: #"someString"]
equals:
myObj.foo = #"someString";
They are orthogonal, different concepts but both dealing with how you interact with properties
Finally, you mention property syntax. Yet another orthogonal concept but related to dealing with properties.
With objective-c, convention is important. Follow them. Properties are the name of the property for the get and set[Name] for the assignment:
- (NSString*)foo
{
return _foo; // defined as (NSString*)_foo in header
}
- (void) setFoo: (NSString*)foo
{
if (foo == _foo)
return;
NSString* curr = _foo;
_foo = [foo retain];
[curr release];
}
Now, who wants to write something like that every time. So, enter #property syntax:
In header:
#property (retain) NSString *foo;
Then in .m:
#synthesize foo;
That's the equivalent of the hand written property accessors. It's compiler syntax sugar which expands the property code based on how you attribute the properties.
Docs:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html
I am trying to understand the purpose of the synthesize directive with property name overriding. Say that I have an interface defined as follow:
#interface Dummy ... {
UILabel *_dummyLabel;
}
#property (retain, nonatomic) UILabel *dummyLabel;
And in the implementation file, I have:
#synthesize dummyLabel = _dummyLabel;
From what i understand, "dummyLabel" is just an alias of the instance variable "_dummyLabel". Is there any difference between self._dummyLabel and self.dummyLabel?
Yes. self._dummyLabel is undefined, however _dummyLabel is not.
Dot syntax expands out to simple method invocations, so it's not specific to properties. If you have a method called -(id)someObject, for example in the case of object.someObject, it will be as if you wrote [object someObject];.
self.dummyLabel //works
self._dummyLabel //does not work
dummyLabel //does not work
_dummyLabel //works
[self dummyLabel]; //works
[self _dummyLabel]; //does not work
Your understanding is incorrect. dummyLabel is the name of the property, and is not an alias for the instance variable - the instance variable is only called _dummyLabel. So the following holds for an instance of Dummy called myObject:
[myObject dummyLabel] works
myObject.dummyLabel works
[myObject _dummyLabel] fails
myObject._dummyLabel fails
myObject->dummyLabel fails
myObject->_dummyLabel depends on the visibility of the ivar (#public, #private, #protected)
[myObject valueForKey: #"dummyLabel"] works
[myObject valueForKey: #"_dummyLabel"] depends on the implementation of +accessInstanceVariablesDirectly (i.e. it will work in the default case where +accessInstanceVariablesDirectly returns YES).
The advantage of having another name
for the ivar than for the property is
that you can easily see in the code
when you are accessing one or the
other - Andre K
I'm not able to find a 'comment' button so I'm having to post as an 'answer'.
Just wanted to expand on Andre's comment - by knowing when you are using the synthesized properties vs the vanilla variable, you know (especially in case of setters) when a variable is being retained/copied/released automatically thanks to your nice setter, vs being manipulated by hand.
Of course if you are doing things right, you probably don't need the help of a setter to retain/release objects properly! But there can be other scenarios too where referring to your ivars as self.ivar instead of _ivar can be helpful, such as when you are using custom setters/getters instead of the default synthesized ones. Perhaps every time you modify a property, you also want to store it to NSUserDefaults. So you might have some code like this:
#interface SOUserSettings : NSObject {
BOOL _autoLoginOn;
}
#property (nonatomic, assign) BOOL autoLoginOn;
#end
#implementation SOUserSettings
#synthesize autoLoginOn = _autoLoginOn;
- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {
_autoLoginOn = newAutoLoginOnValue;
[[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:#"UserPrefAutoLoginOn"];
}
#end
Note: This is just illustrative code, there could be a thousand things wrong with it!
So now, in your code, if you have a line that says _autoLoginOn = YES - you know it's not going to be saved to NSUserDefaults, whereas if you use self.autoLoginOn = YES you know exactly what's going to happen.
The difference between _autoLoginOn and self.autoLoginOn is more than just semantic.
I don't see any big advantage of
renaming _dummyLabel to dummyLabel
In some ObjC runtimes you have a hard time making instance variables invisible to users of the class. For them sticking some prefix (or suffix) on your instance variables can make it clear (or more clear) that you don't want anyone messing with your variables. However you don't want that gunk on your public functions. This lets you get it off.
It could also be useful if you need to maintain an old interface with one set of names at the same time as a new set of APIs with a new set of names (setLastname vs. setSurname).
Old post, but I think its important to mention, that it is recommended to access variables via getters and setters (so, with dot notation). Accessing a field directly (_ivar) is strongly recommended only when initializing it.
There is some good Apple's article:
https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
Last paragraph:
You should always access the instance variables directly from within
an initialization method because at the time a property is set, the
rest of the object may not yet be completely initialized. Even if you
don’t provide custom accessor methods or know of any side effects from
within your own class, a future subclass may very well override the
behavior.