objective C underscore property vs self - objective-c

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.

Related

'does not have member' when calling objective C setter method from Swift

After importing the objective C robbiehanson/XMPPFramework into a swift project (setting up build setting, bridging header, etc). I am able to call normal methods in the imported classes and set properties directly.
However, certain instance methods that set properties cause immediate errors as if they don't exist in the instances I'm calling them on. For example:
- (void)setMyJID:(XMPPJID *)newMyJID
{
[self setMyJID_setByClient:newMyJID];
}
Or even the setMyJID_setByClient:newMyJID method which actually does the setting.
In two separate objective c example projects I have looked at, the setMyJID method is being called from other classes. However, while I am able to call other instance methods on the class, I can't call this one. Since I am not very familiar with objective c, I though this might be because it wasn't declared in the header file, causing some swift specific problem, but attempts to add a declaration for it did not help.
I am able to set the relevant property directly, but this is not only undesirable, I also would like to understand why I am not able to call certain methods.
I am attempting to make the call on an instance of the XMPPStream class like this
//This shows immediate error: XMPPStream does not have a member named 'setMyJID'
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
// This works perfectly
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
Any help would be appreciated.
In the XMPPStream class, myJID is declared as follows:
#property (readwrite, copy) XMPPJID *myJID;
In Objective-C, this means that there are actually two methods on the XMPPStream class that conform to the following signatures:
- (XMPPJID *)myJID;
- (void)setMyJID:(XMPPJID *)myJID;
So, from Objective-C code, you can call them like any other method. However, as you know, you also have the option of using the syntactic sugar in the language known as "dot notation":
// getter with dot notation
XMPPJID *jid = stream.myJID;
// setter with dot notation
stream.myJID = jid;
However, in Objective-C, these dot notation expressions are directly translated into calls to the getter and setter. They're just there to look nice.
Things are different in Swift. When you have a property, like this one:
var myJID: XMPPJID
this does not mean that there exist separate getter and setter methods, like you might be imagining:
func myJID() -> XMPPJID {}
func setMyJID(jid: XMPPJID) {}
In Swift, you must access properties using dot syntax.
Knowing this, your problem becomes obvious. When you tried:
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
Swift tried to run the instance method setMyJID of stream, and found, rightly, that it did not exist! This, of course:
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
works perfectly, because you're setting a property as Swift requires.
As an educational aside, you may sometimes see cases where, when accessing Objective-C properties from Swift, you not only can, but must use the getter and setter methods - dot notation won't even work! This seems totally counterintuitive, but there's a good reason for why this happens. One example of this that I can think of off the top of my head is the verbosely-named UIView property translatesAutoresizingMaskIntoConstraints, used for view layout. If you try to use it in Swift, like so:
// Set translatesAutoresizingMaskIntoConstraints to false on self
translatesAutoresizingMaskIntoConstraints = false
you would get a compilation error! Specifically,
Cannot assign to 'translatesAutoresizingMaskIntoConstraints' in 'self'
Why? The answer lies in the UIView headers:
- (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
- (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
It turns out that this "property," like many others in the Cocoa frameworks, is actually just a pair of methods that look like property accessors. Because of how Objective-C translates dot notation into method calls, you'd never notice before. Now, though, Swift is stricter – to get and set this "property," you must call the appropriate methods.

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.

In Objective-C, do we have to use self.var or just var to reference a property of self?

If I add a property to the ViewController
#property (strong, atomic) UIView *smallBox;
and synthesize it in the .m file, the variable can actually be referenced just by smallBox inside of any instance methods.
But then, self.view cannot be replaced by view, even though view is defined as a property of UIViewController too. Why the difference and what is the rule?
self.view and view/_view are not the same thing. Depending on how you create your instance variables, view or _view refer to the actual object instance variable. It is dangerous to access this directly, and you should only do so in init, dealloc or in accessors. Everywhere else, you should use self.view.
self.view is exactly the same as [self view], which passes the message "view" to the object "self" an returns the result. By default, when an object receives a message, it executes the method with that name, and the default implementation of view will return the value of the related instance variable (either view or _view).
In older versions of Xcode, #synthesize view would create an instance variable called view. In the latest versions of Xcode, declaring a property view will will automatically create an instance variable called _view in many cases, even without #synthesize. This change makes it easier to notice when you are accessing the ivar directly.
In short:
except in init, dealloc and the view accessors (if you custom write them), always use self.view.
In those methods, you should refer to it as _view.
If you are writing for the latest Xcode, do not include #synthesize at all. If you are writing for a slightly older Xcode, use #synthesize view=_view;
self.view does not mean "the value of the instance variable." It means "the result of passing the message 'view'" which is generally implemented as returning the instance variable.
You can't access the view member directly because it's declared as #package visibility in UIViewController. This prevents your code from accessing it. (Normally, you wouldn't want to access instance variables of your superclasses directly anyway.)
For your class's own properties, you can access the instance variable directly, but you need to be aware of the memory management implications of this. (As well, as Rob points out, as any other behaviours you're side-stepping by avoiding the accessor.)
Apple defined properties usually contain an underscore before their name, so when you use self.view, it is actually getting the instance variable _view from the object. You cannot use _view in code, as it will cause a linker error on compiling, but Xcode will still highlight it for you. Another way of accessing the instance variable for self.view is by self->_view, but again, this causes a linker error. The reason for these linker errors is because the compiled libraries do not contain the symbols for _view; even if its declaration can be found in UIViewController.h.

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.