Difference between _ and self. in Objective-C - ios

Is there a difference between using the underscore and using the self keyword in Objective-C when calling an #property?
Property declaration:
#property (weak, nonatomic) NSString *myString;
Calling #synthesize on the property:
#synthesize myString = _myString;
Is there a difference if I want to use it in my code? When? In the getter/setter?
self.myString = #"test";
_myString = #"test";

self.myString = #"test"; is exactly equivalent to writing [self setMyString:#"test"];. Both of these are calling a method.
You could have written that method yourself. It might look something like this:
- (void)setMyString:(NSString*)newString
{
_myString = newString;
}
Because you used #synthesize, you don't have to actually bother writing that method, you can just allow the compiler to write it for you.
So, from looking at that method, it looks like calling it will do the exact same thing as just assigning a value to the instance variable, right? Well, it's not so simple.
Firstly, you could write your own setter method. If you do so, your method would get called, and it could do all sorts of additional things as well as setting the variable. In that case, using self.myString = would call your method, but doing _myString = would not, and thus different functionality would be used.
Secondly, if you ever use Key Value Observing, the compiler does some very clever tricks. Behind the scenes, it subclasses your class, and overrides your setter method (whether it's one you wrote yourself or one generated by synthesize), in order to make the calls to willChangeValueForKey: that are needed for Key Value Observing to work. You don't need to know how this works (although it's quite interesting if you want some bedtime reading!), but you do need to know that if you want Key Value Observing to work automatically, you have to use setter methods.
Thirdly, calling the setter method even if you're relying on synthesize to write one gives you flexibility for the future. You might want to do something extra whenever a value is changed, and at the point you discover you want to do that, you can manually write a setter method — if you're in the habit of always using self.myString =, then you won't need to change the rest of your code to start calling the new method!
Fourthly, the same applies to subclasses. If someone else was to subclass your code, if you use the setters then they could override them to adjust the functionality.
Any time you access the instance variable directly, you're explicitly not providing a way for extra functionality to be hooked in at that point. Since you or someone else might want to hook in such functionality in the future, it pays to use the setters all the time, unless there's a good reason not to.

You are correct - the first version (self.myString) calls the synthesized getter/setter and the second version access the private member variable directly.
It looks like you are using ARC, so in that case it doesn't make that much of a difference. However, if you aren't using ARC, it can make a difference as assigning to the private member directly won't trigger the automatic retain/release or copy/release logic that is generated for you by using synthesize.

The _ (underscore) is simply a convention, as explained in this question.
When you don't prefix a property access with self., you are accessing the underlying variable directly, as in a c struct. In general, you should only ever do this in your init methods and in custom property accessors. This allows stuff like computed properties and KVC to work as intended.

There is a tip not mentionend, the access using underscore is faster and the access using self is safer (KVC). Maybe this can summarise when you have to use each one.

Related

Using property accessors on viewDidLoad - Objective C

As far as I know you should always use accessors to access or modify a property, except in two scenarios:
init
dealloc
Don’t Use Accessor Methods in Initializer Methods and dealloc The only
places you shouldn’t use accessor methods to set an instance variable
are in initializer methods and dealloc. To initialize a counter object
with a number object representing zero, you might implement an init.
This exceptions are because calling accessors when the view is not completely initialised might raise issues when overriding the setters/getters (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html)
So, according to this the use of accessors on viewDidLoad should be perfectly fine, and even recommended, however in most of the codes available on internet developers use _ivars on viewDidLoad and I wonder why. Is there a reason for using property _ivars instead of accessors in viewDidLoad?
One of the most valuable post about using accessors in init/dealloc method
https://www.mikeash.com/pyblog/friday-qa-2009-11-27-using-accessors-in-init-and-dealloc.html
you should always use accessors to access or modify a property
Where did you read this?
When you want to access a property, you can use _ivar (or self->_ivar) to access the instance variable directly without passing by the getter, it would be faster that resolving and executing the getter.
However, if you use a custom getter then it won't be executed.
Often property accessors are overridden to update the view, which is inefficient if the view is not visible yet. So it is possible the code you found that ivar directly is using that to prevent that. However, much better is to use the property but check if the view is visible and only update if necessary. The same method can be called from viewWillAppear.

Properties and their backing ivars

Hi imagine I have properties in the .h file:
#property (nonatomic) NSString * myText;
#property (nonatomic) SomeClass * someObj;
Now, in the class implementation.
Say, I didn't forget to use synthesize, and I called:
#synthesize myText, someObj;
Now say in code I forget to put self before the property name (and directly refer to the ivar):
myText = #"Hello";
someObj = [[SomeClass alloc] init];
My question is: is this a problem? What problems can it result in? Or it is no big deal?
ps. Say I am using ARC.
My question is: is this a problem?
This is called "direct ivar access". In some cases, it's not a problem, but a necessity. Initializers, dealloc, and accessors (setters/getters) are where you should be accessing self's ivars directly. In almost every other case, you would favor the accessor.
Directly accessing ivars of instances other than self should be avoided. Easy problem here is that you may read or write at an invalid address (undefined behavior), much like a C struct. When a messaged object is nil, the implementation of that message is not executed.
What problems can it result in?
Biggest two:
You won't get KVO notifications for these changes
And you are typically bypassing the implementation which provides the correct semantics (that can be justified). Semantics in this case may equate to memory management, copying, synchronization, or other consequences of a change of state. If, say, a setter is overridden, then you are bypassing any subclass override of that setter, which may leave the object in an inconsistent state.
See also: Why would you use an ivar?
For clarity, I recommend always using
self.propertyname
as opposed to
propertyname
as this removed any confusion between what variable belong to the class or have been declared locally above in the method.
To enforce this, try to avoid using #synthesize at all, which is only needed if you provide both custom getter and setter (but not one or the other)
The compiler automatically allows you to use _propertyname in the getter/setter (which is necessary to prevent recursive calls of the function)
You should not access the underlying instance variables by accident, only if you plan to do so.
Unexpected side effects may be that KVO doesn't work, overriding accessor methods are not called and the copyand atomic attributes have no effect.
You don't need to use #synthesize since Xcode 4.4, if you use default synthesis the compiler does an equivalent of
#synthesize myText = _myText;
so that
_myText = #"Hello";
self->_myText = #"Hello";
are equivalent and myText = #"Hello"; results in an "undefined identifier" compiler error.
If you use just #synthesize myText the compiler does (for backward compatibility reasons):
#synthesize myText = myText;
which is error prone.
Note that there are valid reasons to use the underlying instance variables instead of the accessor - but it's bad style to do this by accident.
For 30 years now, the recommended practice has been:
use getter/setter methods or the new . operator to read and write ivars.
only access ivars directly when you must.
pick ivar names to prevent accidentally using them, unless the ivar is one that will always be accessed directly (that is why the default behaviour and convention is to prefix ivars with an underscore).
You need to access ivars directly in a few situations:
Manual memory management requires it. You won't need this if ARC is enabled.
If you are going to read the variable variable millions of times in quick succession, and you can't assign it to a temporary variable for some reason.
When you're working with low level C API, it probably needs a pointer to the ivar, Apples libxml2 sample code accesses ivars directly for example.
When you are writing the getter or setter method yourself, instead of using the default #synthesize implementation. I personally do this all the time.
Aside from these situations (and a few others), do not access ivars directly. And prefix all ivars with an underscore, to make sure you don't accidentally access them and to prevent them appearing in xcode's autocomplete/intellisense while you code.
The two main reasons for the convention are:
Getter/setter methods and properties can be kept around when the underlaying memory structure of your class changes. If you rename an ivar, all code that reads the ivar will break, so best to have zero code or almost no code that accesses ivars directly.
Subclasses can override getters and setters. They cannot override ivars. Some people think subclasses shouldn't be allowed to override getters and setters - these people are wrong. Being able to override things is the entire point of creating a subclass.
Fundamental features like KVC and KVO can fall apart if you access ivars directly.
Of course, you can do whatever you want. But the convention has been around for decades now and it works. There is no reason not to follow it.
Contrary to what other answers seem to agree upon, I would recommend to always use direct ivar access unless you are very clear about what you are doing.
My reasoning is simple:
With ARC, it's not even more complicated to use direct property access, just assign a
value to the ivar and ARC takes care of the memory management.
(And this is my main point:) Property accessors may have side-effects.
This is not only true for property accessors you write, but may also be true for
subclasses of the class you are implementing.
Now these accessors defined in subclasses may very well rely on state that the subclass
sets up in it's initializer, which has not executed at this point, so you calling those
accessors might lead to anything from undefined state of your object to your application
throwing exceptions and crashing.
Now, not every class may be designed to be subclassed, but I think it's better to just use one style everywhere instead of being inconsistent depending on the class you are currently writing.
On a side note: I would also recommend to prefix the name of every ivar with an _, as the compiler will do automatically for your properties when you don't #synthesize them.

Why use "self" and what does it mean? [duplicate]

This question already has answers here:
What is self in ObjC? When should i use it?
(6 answers)
Closed 9 years ago.
So, I just started learning Objective-C and I've come across this "self" thing. I've only ever used C, but I think it's used in java too maybe? Can someone explain? Here's an example:
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
UILabel *myDisplay = [self display]; //why this?
}
Why isn't it just this?
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
UILabel *myDisplay = display; //why not like this?
}
display is a UILabel *
[self display], or self.display, refers to a property / method (property is just a shortcut for get/set method anyway) if you have something like this in the .h file
#property (weak, nonatomic) UILabel* display;
or
-(UILabel*)display;
Just display, or self->display refers to an instance variable. This is valid when you have declared an instance var like this:
#implementation MyClass {
UILabel* display;
}
If you have declared the property display in the .h file and haven't changed its default, the corresponding instance var will be _display (note the underscore), in which case the following will be the same:
self.display and self->_display
In this case it's an objective C messaging thing. When you see the brackets it's doing this:
[Object Message]
Basically self is the object and display is the message your sending it. Sending it a message is like a method call in another language, but a little different under the hood. So something like this:
[self doSomethingCool];
in objective C would translate to something like this in another language:
this.doSomethingCool();
of course if running a method on another object you'll replace self with that object like:
[myObject doSomethingCool];
in a lot of languages you don't really need to have the "this" in front of your method call, it's implied that if you don't include it you're running the method in the object you're working with. I got burned pretty early on when I started with something similar. I had a call to a datalayer method where you could save an object and it would give you an integer back. When I was saving the object I didn't put the self in front of the method call and it was essentially generating a new object and saving it and I wasn't getting the right integer back.
Using "self" just explicitly tells it "I'm using THIS object". Same thing with properties, I always use "self.MyProperty" instead of "MyProperty" because I want to be explicit and make sure I'm using the MyProperty of the object I'm working in. It's semi rare for a defect like that to hit you, where you expect to be using a certain object and the environment thinks you're using another, but man when you run into one it's a head scratcher because everything looks right.
The word self refers to the current object, which is your view controller instance in this case, and combining it with a method name, which is display, means you are sending the message display to self which is the view controller. This will invoke the method display declared in your view controller instance.
You might declare the display method in your view controller, for example:
- (UILabel)display
{
//your display method implementation returning UILabel instance
}
For the second one, it means you are referring to display variable. For example:
UILabel *display = [[UILabel alloc] init];
display is not a UILabel * - it might be a property with that type, or a method which returns a value of that type, but these a rather different things.
You need to go an read something about object oriented programming. The self in Objective-C is the current object reference, other OO languages call it this - both Java and C++ use that name. Understanding objects and methods is fundamental to using any of these languages.
There's a very good explanation of this here:
http://useyourloaf.com/blog/2011/02/08/understanding-your-objective-c-self.html
The key section for your question is the section on Objective-C 2.0 dot syntax:
Objective-C Dot Syntax
The dot syntax was introduced with Objective-C 2.0 and generates a lot
of debate. A number of experienced and long time Cocoa programmers
recommend avoiding it completely. Others such as Chris Hanson have a
different view about when to use properties and dot notation.
Whichever side of the argument you fall I guess the main thing is to
be consistent.
Anyway the main thing to understand about the dot syntax is that the
following two statements are doing the same thing:
self.timestamp = [NSDate date];
[self setTimestamp:[NSDate date]];
The dot is just a shortcut for the more traditional Objective-C method
call. Any time you see a dot you can replace it with the equivalent
square bracket method call syntax. It is important to understand
however that this is not the same as writing the following:
timestamp = [NSDate date]; Without the self object and the dot we are
no longer sending an object a message but directly accessing the ivar
named timestamp. Since this bypasses the setter method we will
overwrite the timestamp ivar without first releasing the old NSDate
object. We will also not retain the new object that we are assigning.
Both of these situations are bad!
Keep in mind that the examples were written without using ARC, so there's a lot of references to memory management, retain, release etc. It is however useful to see these examples so that you have some idea of what ARC is doing in the background.
In your example, you are not referring to the actual display property with [self display] you are in fact referring to an instance method of the "self" object which in this case is your UIViewController.

If I'm creating completely custom getter and setter methods do I still need an #property declaration?

So I want to have a "property" on a class but I don't want to just hold that property in memory, I want to actually store it as an NSUserDefault and retrieve it when you get that property.
So as such I have methods like this:
- (void)setUser:(User *)user {
// actually set the user as an NSUserDefault here
}
- (User *)user {
// get the user from the NSUserDefaults and return it
}
As I'm building these methods to do the work for me is there any point in having an #property declaration in the header file?
I'm getting mixed messages. Some people say that you should declare the property to force people to use the getter/setter methods, but I can't see why people wouldn't be forced to use those methods if they're all that are available?
Just looking for a bit of clarification.
Many thanks.
You should use #property because that's the modern way to define properties on Objective-C objects, even if you implement the setter and getter yourself.
Rather than relying on convention you are making your intentions much clearer to the compiler. You will also get better syntax highlighting when using dot-notation in the IDE (although that's arguably an Xcode bug).

What is the difference between an #property and getters/setters for methods that "look" like properties?

I understand the key differences/process. A property creates the getters and setters for a class variable. It also (now) synthesises it with a private variable with a _ prefix.
Great.
Now, I want some methods to act like a property. So I have a UIView subclass which has a UILabel subview.
I want to create the two methods - (NSString *)text and setText:(NSString *)text in order to set and get the text of the UILabel.
Obviously this is ACTING like a property (you can do [myCustomElement text] and [myCustomElement setText:#"whatever"]) so I feel like I should define a property, but what use would this have, if any?
My getters and setters will look like this:
- (NSString *)text {
return self.textLabel.text;
}
- (void)setText:(NSString *)text {
self.textLabel.text = text;
}
You could do this, but I would discourage you from doing so. To have methods that look like standard accessor methods (getters and setters), but are really updating UI controls is only going to be a source of confusion in the future. This only undermines your code's readability when methods are performing functions that don't conform to conventional practices. Plus you already have a property for your textLabel, so these methods don't buy you very much.
By the way, the standard auto-generated accessor methods provide other useful functions (doing the necessary memory management on the basis of the qualifiers you specify when you define the property, enabling key value observation for some future date where you might need such functionality, etc.), so I would be reticent to replace them with your own methods unless you are expert in these concepts.
If you're doing stuff different than the standard accessor methods, I'd suggest using method names that are less likely to be a source of confusion in the future.
text is already a property (called text) of yourCustomElement property textLabel ( that's why you access it using dot notation yourCustomElement.textLabel.text)
in this example the getters/setters for the text property should/can only be inside the textLabel Class
Those two methods are just convenience methods to set/get a property of a property (fine, but they're not getters/setters and shouldn't look them)
I think for your specific example, it's fine not to define a property.
Properties (as far as I can work out) provide handy shorthands that ensure proper retain/releasing (when appropriate) under the hood.
http://useyourloaf.com/blog/2011/02/08/understanding-your-objective-c-self.html
what use would this have, if any?
There are many Uses :
1) You can use properties to do some Calculations , Updating Object's State , or some Caching like stuff.
2) Have you heard about Key-Value Coding (KVC) and Key-Value Observing (KVO) in Cocoa ? They are depended on Properties. Check : KVC Programming Guide and KVO Programming Guide.
3) Using properties you could put some memory management code in the accessors.
If you declare it as a property, and override the getters/setters, then you have access to using dot notation to change or retrieve the value.
Ex:
myCustomElement.text = #"whatever";
long storry short:#synthesis generates getters and setters. So using synthesis saves you typing.
Your code however is not the same as #synthesis textLabel because your code allows only changing the labels text. #synthesis would allow changing all properties.
Here is some useful information about #synthesis / getters / setters
http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html

Resources