Objective-C use property and it's storage location. Difference? - objective-c

What is the difference between property name and property storage location?
I must use only property name or mm what is the point to use first or the second?
Here is my example:
#implementation Car
#synthesize carSpeed = _carSpeed;
-(void) someMethod:(double)speed
{
self.carSpeed = speed; // this is the same am I right?
_carSpeed = speed;
}
#end

When directly accessing the instance variable (the storage location) there is no way other code can be notified of this change and do something about this. Using the property (using the dot syntax) is nothing more than a message send to the setter.
self.carSpeed = speed;
is exactly the same as
[self setCarSpeed: speed];
For once this enables automatic KVO to work, observers for this property will be notified that it changed.
Also since this is a regular message send the regular message dispatch happens. So you can override the setter in a subclass to change it’s behavior. Or you can change the implementation of the getter and setter to use some other kind of storage for the value instead of an instance variable without having to change any code that needs to change or read that property value.
Before we had ARC another important reason to use the accessors everywhere was that they are supposed to take care of memory management.

self.carSpeed = speed;
This uses setter method
Whereas,
_carSpeed = speed;
uses directly the ivar or property through the alias created.
Using . notation gives you the facility to access them from outside the class and setters and getters are in public zone.
Whereas, _carSpeed makes it local to the class. And more it is a old convention.
Synthesized property and variable with underscore prefix: what does this mean?

Related

Different Ways To Declare Objective C Instance Variables [duplicate]

I have been unable to find any information on this topic and most of what I know about it has come by complete accident (and a few hours of trying to figure out why my code wasn't working). While learning objective-c most tutorials I have found make variables and properties with the same name. I don't understand the significance because it seems that the property does all the work and the variable just kind of sits there. For instance:
Test.h
#interface Test : NSObject {
int _timesPlayed, _highscore;
}
#property int timesPlayed, highscore;
// Methods and stuff
#end
Test.m
#implementation Test
#synthesize timesPlayed = _timesPlayed;
#synthesize highscore = _highscore;
// methods and stuff
#end
What I know
1) Okay so today I found out (after hours of confusion) that no matter how much changing you do to the properties highscore = 5091231 it won't change anything when you try to call [test highscore] as it will still be returning the value of _highscore which (I think) is the ivar that was set in test.h. So all changing of variables in test.m needs to be changing _highscore and not highscore. (Correct me if I'm wrong here please)
2) If I understand it correctly (I probably don't) the ivars set in test.h represent the actual memory where as the #properties are just ways to access that memory. So outside of the implementation I can't access _highscore without going through the property.
What I don't understand
Basically what I don't get about this situation is whether or not I need to use the ivars at all or if I can just use #property and #synthesize. It seems like the ivars are just extra code that don't really do anything but confuse me. Some of the most recent tuts I've seen don't seem to use ivars but then some do. So is this just a coding preference thing or is it actually important? I have tried searching through Apple's Documentation but I get rather lost in there and never seem to find what I'm looking for. Any guidance will be greatly appreciated.
You can think of the syntax for synthesizing properties as #synthesize propertyName = variableName.
This means that if you write #synthesize highscore = _highscore; a new ivar with the name _highscore will be created for you. So if you wanted to you could access the variable that the property is stored in directly by going to the _highscore variable.
Some background
Prior to some version of the compiler that I don't remember the synthesis statement didn't create the ivar. Instead it only said what variable it should use so you had to declare both the variable and the property. If you synthesized with a underscore prefix then your variable needed to have the same prefix. Now you don't have to create the variable yourself anymore, instead a variable with the variableName that you specified in the synthesis statement will be created (if you didn't already declare it yourself in which case it is just used as the backing variable of the property).
What your code is doing
You are explicitly creating one ivar called highscore when declaring the variable and then implicitly creating another ivar called _highscore when synthesizing the property. These are not the same variable so changing one of them changes nothing about the other.
Should you use variables or not?
This is really a question about preference.
Pro variables
Some people feel that the code becomes cleaner if you don't have to write self. all over the place. People also say that it is faster since it doesn't require a method call (though it is probably never ever going to have a measurable effect on your apps performance).
Pro properties
Changing the value of the property will call all the necessary KVO methods so that other classes can get notified when the value changes. By default access to properties is also atomic (cannot be accessed from more then one thread) so the property is safer to read and write to from multiple thread (this doesn't mean that the object that the property points to is thread safe, if it's an mutable array then multiple thread can still break things really bad, it will only prevent two threads from setting the property to different things).
You can just use #property and #synthesize without declaring the ivars, as you suggested. The problem above is that your #synthesize mapped the property name to a new ivar that is generated by the compiler. So, for all intents and purposes, your class definition is now:
#interface Test : NSObject {
int timesPlayed;
int highscore;
int _timesPlayed;
int _highscore;
}
...
#end
Assigning a value directly to the ivar timesPlayed will never show up if you access it via self.timesPlayed since you didn't modify the correct ivar.
You have several choices:
1 Remove the two ivars you declared in your original post and just let the #property / #synthesize dynamic duo do their thing.
2 Change your two ivars to be prefixed by an underscore '_'
3 Change your #synthesize statements to be:
#implemenation Test
#synthesize timesPlayed;
#synthesize highscore;
...
I typically just use #property and #synthenize.
#property gives the compiler and the user directions on how to use your property. weather it has a setter, what that setter is. What type of value it expects and returns. These instructions are then used by the autocomplete (and ultimately the code that will compile against the class) and by the #synthesize
#synthesize will by default create an instance variable with the same name as your property (this can get confusing)
I typically do the following
#synthesize propertyItem = _propertyItem;
this will by default create a getter and a setter and handle the autorelease as well as create the instance variable. The instance variable it uses is _propertyItem. if you want to access the instance variable you can use it as such.
_propertyItem = #"Blah";
this is a mistake tho. You should always use the getter and setter. this will let the app release and renew as needed.
self.propertyItem = #"Blah";
This is the better way to handle it. And the reason for using the = _propertyItem section of synthesize is so you cannot do the following.
propertyItem = #"Blah"; // this will not work.
it will recommend you replace it with _propertyItem. but you should use self.propertyItem instead.
I hope that information helps.
In your example, #synthesize timesPlayed = _timesPlayed; creates a new ivar called _timesPlayed and the property refers to that ivar. timesPlayed will be an entirely separate variable with no relation whatsoever to the property. If you just use #synthesize timesPlayed; then the property will refer to timesPlayed.
The purpose of the underscore convention is to make it easier to avoid accidentally assigning directly to an ivar when you want to be doing it through the property (i.e. through the synthesized setter method). However, you can still acces _timesPlayed directly if you really want to. Synthesizing a property simply auto-generates a getter and setter for the ivar.
In general you do not need to declare an ivar for a property, although there may be special cases where you would want to.
This may be an old question.. but in "modern times", #synthesize- is NOT necessary.
#interface SomeClass : NSObject
#property NSString * autoIvar;
#end
#implementation SomeClass
- (id) init { return self = super.init ? _autoIvar = #"YAY!", self : nil; }
#end
The _underscored backing ivar IS synthesized automatically... and is available within THIS class' implementation, directly (ie. without calling self / calling the automatically generated accessors).
You only need to synthesize it if you want to support subclass' ability to access the _backingIvar (without calling self), or for myriad other reasons, described elsewhere.

Dot vs arrow notation in Objective-C for non structs

I've seen examples of arrow notation used for structs. In one tutorial, I saw this syntax in a view controller implementation file:
self->webView.canGoBack) backButton.enabled = YES;
I have no idea why they did not use dot notation. No explanation was given. I tried this in a simple project that has a button and text field. Below is what I put in the button press method:
//header file
#property (strong, nonatomic) IBOutlet UITextField *myInputField;
//implementation file
self.myInputField.text = #"another test";
//self->_myInputField.text = #"text field test";
Either line of code works without issue. So why use one of the above lines over the other?
Also, notice that the arrow notation produces _myInputField.text. What is the significance of the underscore?
In Objective-C, objects are also c structs. If you're new to the language, that knowledge will get you in more trouble than it will help. But it helps explain what you're seeing.
An Objective-C property is a helpful construct that creates an ivar in the object (a new field in the class's struct) that defaults to the property name prefixed by an underscore. A property will also create getter and setter methods, e.g. - (UITextFeild *)myInputField and - (void)setMyInfputField.
Dot notation is Objective-C syntactic sugar that calls the Objective-C setter and getter methods. The -> arrow notation is C syntax that will dereference the object's pointer and access the struct field for the object's ivar.
It is important to understand that the dot syntax is actually generating calls to these methods, so you don't try and override those methods and inadvertently include calls to themselves.
The default implementation of a generated method like - (UITextFeild *)myInputField looks something like this
- (UITextFeild *)myInputField {
return self->_myInputField;
}
But Objective-C has yet another syntactic helper allowing you to access _myInputField without writing out self->. So the following implementation is identical.
- (UITextFeild *)myInputField {
return _myInputField;
}
There are some good reasons for using direct ivar access -- the biggest reasons being implementation of custom setters and getters, performance, and careful control over KVO language features. But in modern Objective-C it should be avoided unless you really know what you're doing.
If you want to learn more, read Apple's documentation on Objective-C
self.myInputField.text = #"another test";
That code calls the myInputField getter method. There can be good reason for doing this, so it is usually safest.
self->_myInputField.text = #"text field test";
That code directly accesses the _myInputField instance variable.
The myInputField getter method in this case also accesses the _myInputField instance variable, which is why the two calls seem to do the same thing. But that is just an implementation detail; it is perfectly possible for a getter method to access a differently named instance variable, to perform other actions (side effects), or to access no instance variable at all.

objective C underscore property vs self

I'm was playing around with the standard sample split view that gets created when you select a split view application in Xcode, and after adding a few fields i needed to add a few fields to display them in the detail view.
and something interesting happend
in the original sample, the master view sets a "detailItem" property in the detail view and the detail view displays it.
- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
i understand what that does and all, so while i was playing around with it. i thought it would be the same if instead of _detailItem i used self.detailItem, since it's a property of the class.
however, when i used
self.detailItem != newDetailItem
i actually got stuck in a loop where this method is constantly called and i cant do anything else in the simulator.
my question is, whats the actual difference between the underscore variables(ivar?) and the properties?
i read some posts here it seems to be just some objective C convention, but it actually made some difference.
_property means you are directly accessing the property.
self.property means you are using accessors.
In your case, in the setter method you are calling it, creating a recursive call.
In the course of your experiment, you've set up an endless loop which is why the simulator goes non-responsive.
Calling self.detailItem within the scope of setDetailItem: calls setDetailItem: recursively since your class implements a custom setter method for the property detailItem.
I would refer you to the Apple documentation on declared properties for the scoop on properties, ivars, etc; but briefly, declared properties are a simplified way of providing accessor methods for your class. Rather than having to write your own accessor methods (as we had to do before Objective-C 2.0) they are now generated for you through the property syntax.
The properties are basically a way of the compiler to generate a setter and getter for a given instance variable.
So when you use something like:
id detailItem = self.detailItem;
what you are doing under the hood is:
id detailItem = [self detailItem];
Same for:
self.detailItem = otherDetailItem;
would be:
[self setDetailItem:otherDetailItem];
So when you write the setter yourself.. you get in an infinite loop since you access the method itself in itself.
You can freely make use of the 'self.' notation in your class, just not when you're overriding the setter or accessor because of the mechanism I described above.
Cases in a class where I use the . notation over simply accessing the ivar is when I change the value, you never know inside your class what needs to happen when you change the value. do you have something in terms of a status that should notify some delegate that a status changed? Usually this is not the case, however, just by using the . notation you are making sure that in the future you won't have to refactor some code if you did decide to do some magic in your setter method.
I'll make an example (without ARC enabled):
#property (nonatomic, retain) NSNumber* number;
If you don't synthesize it, you can access it this way:
self.number= [NSNumber numberWithBool: YES];
This case the number is retained.If instead you synthesize it and don't use the property:
#synthesize number;
Later in the file:
number=[NSNUmber numberWithBool: YES];
You haven't used the property, so the number is not retained.That makes a relevant difference between using accessors and synthesized properties.

when to use "willChangeValueForKey" and "didChangeValueForKey"?

I saw these lines in a demo project, but I couldn't understand why it did that.
[self willChangeValueForKey:#"names"];
[self didChangeValueForKey:#"names"];
It called didChangeValueForKey immediately after willChangeeValueForKey.
Does it make any sense?
Furthermore, when should be the right time to call this two methods?
Thanks a lot!! :)
This is, in fact, an anti-pattern. You should not call -willChangeValueForKey: followed by -didChangeValueForKey: without any intervening actual property change. In some cases, doing so can mask KVO problems elsewhere in your code and force observers to update their state related to the property in question. Ultimately, however, you (or the author of the example you cite) should fix the rest of the code so that this anti-pattern is unnecessary.
The correct usage of -will|didChangeValueForKey: is when you are modifying a property without using KVC-compliant accessors/setters such that the KVO mechanism would not notice the change. For a contrived example, consider modifying the backing instance variable for an attribute directly:
#interface Foo
{
int bar;
}
#end
#implementation Foo
- (void)someMethod
{
bar = 10;
}
#end
KVO observers that had registered for notification of changes in the bar property would not recieve notification of the change to bar in -someMethod. To make the KVO machinery work, you could modify -someMethod:
- (void)someMethod
{
[self willChangeValueForKey:#"bar"];
bar = 10;
[self didChangeValueForKey:#"bar"];
}
Of course, it would be better to use a #property declaration and to use KVC-compliant accessors/setters (either manually coded or #synthesized), but this is a contrived example.
KVO will operate correctly with custom setters for properties; this has always been the case for NSObject-derived classes. The runtime machinery looks for an invocation of the relevant setter method, and implicitly calls "willChangeValueForKey" prior to executing the setter, then implicitly calls "didChangeValueForKey" after the setter completes.
You can disable this automatic behavior if you wish to have more fine-grained control over KVO notifications. As mentioned above, readonly properties whose value you change by modifying the backing ivar, or whose values are derived by calculation, are places where you would use the manual notifications (although there is a mechanism, keyPathsAffectingValueFor, where you can tell the runtime that the value of a property is dependent on the change of another property, and it will send the change notification as appropriate.) To disable the automatic behavior on a per-property basis, you put in a class method + (BOOL) automaticallyNotifiesObserversOf and return NO.
I often disable automatic KVO notifications, because I have found that a KVO notification is generated when invoking a setter, even if the value of the property is being set to the same as its current value (e.g. no change). I wish to suppress the pointless notification for efficiency's sake:
+ (BOOL)automaticallyNotifiesObserversOfMyProperty
{
return NO;
}
- (void)setMyProperty:(NSInteger)myProperty
{
if(_myProperty != myProperty)
{
[self willChangeValueForKey:#"myProperty"];
_myProperty = myProperty;
[self didChangeValueForKey:#"myProperty"];
}
}
A good discussion can be found in the NSKeyValueObserving.h header, that you can navigate to by CMD+clicking on the method names "willChangeValueForKey" and "didChangeValueForKey" in XCode.
Those have to do with manually controlling key value observing. Normally the system takes care of it but these allow you some control. Look at this documentation to understand when and how to use them here.
Agree with Barry. I just meet the same problem. Here is a case of using those two methods.
I declared a readonly property. So I can't use the property's accessor to change the value.
#property (nonatomic, readonly) BOOL var;
When I want to change the "var", I need to call these two methods manually. Otherwise, observers won't get notified.
self willChangeValueForKey:#"var"];
var = YES;
[self didChangeValueForKey:#"var"];
If you want to do stuff just before the value gets changed, use willChangeValueForKey.
If you want to do stuff just after the value gets changed, use didChangeValueForKey.
Edit: ignore me, was reading too fast - Barry is right :-)
Be really careful when overriding didChangeValueForKey:. The best thing is not to do it at all. But if you do, make sure you call super, otherwise you will have a memory leak as demonstrated here: https://github.com/jfahrenkrug/KVOMemoryLeak
if you rewrite property getter methods, please use it.
#property (assign, nonatomic, getter=isLogined) BOOL logined;
Posting this in July 2013, and it no longer seems to be necessary to call will/didChangeValueForKey. It seems to be taken care of automatically, even if you have a custom setter.

Difference between accessing property methods and class fields (Objective-C)

Assume that I have this piece of code:
#interface Foo : NSObject {
Bar *bar;
}
#property (retain, nonatomic) Bar *bar;
#end
When using this field/property, is there any difference between lines:
[self.bar doStuff];
and
[bar doStuff];
?
When doing assignment, property method will perform correct retaining, but what about the read access to the property, as described above? Is there any difference?
There is a big difference.
[self.bar doStuff] is equivalent to [[self bar] doStuff]
[bar doStuff] is equivalent to [self->bar doStuff]
The former uses the accessor method, the latter just accesses the instance variable bar directly.
If you use the #synthesize directive on your bar property, the compiler will generate two methods for you:
- (void)setBar:(Bar*)b;
- (Bar*)bar;
Also note, that the compiler generated setter method is retaining your Bar instance as you told it in the #property declaration.
Using the accessor self.bar is translated into a method call: [self bar]. The period syntax is just for looks. Accessing the member variable directly doesn't involve an extra function call, and is therefore slightly faster. It really only matters if you're accessing it within a loop, or in some process where that difference will add up. (On the iPhone) The setters created for properties also have some extra overhead for doing key value coding. A KVO notification is sent when you call "setBar:" or say "self.bar =" , so calling it over and over will result in a flood of notifications.
Jim is right, though - there's no functional difference between a nonatomic #property and a direct use of the variable in your code. Unless you're really concerned with the speed, using the property is probably your best bet.
A synthesized (or correctly hand-written) nonatomic accessor will be functionally equivalent to
- (Bar *)bar
{
return bar;
}
so there is no functional difference between your two examples.
However, outside of -dealloc or your initializers, consistently accessing the property via its accessor is a good idea.
If you assign value to your field with a convenient constructor of a Bar class, your Bar field will become a Zombie sooner than your Bar Property with Retain option, because reference count is not incremented by assigning to fields, and sometimes you run into "accessing deallocated objects" error.