This question already has answers here:
Using self->ivar when accessing instance variables directly
(4 answers)
Closed 7 years ago.
So if I have in iOS (with Objective C, not sure if this the same for Swift) e.g.
#property (nonatomic, copy) NSString *aString;
And then some where in the code I have
// Simple ivar access in some method
_aString = anyStringOrNil;
// Self-> ivar access in some other method
self->_aString = anyStringOrNil;
I would like to know the differences between using one or the other
As you posted, those are identical. There is a difference between directly accessing the ivar and going through a property however. If you set the string as so:
self.aString = someString;
That would go through the automatically generated setter which, based on your property declaration would make a copy of someString. This is preferable in the case of working with mutable strings. You don't want the string to change out from under you. In both examples that you used, you are directly setting the value of _aString to the string reference, so if the string is a mutable string that is owned by someone else, it could change without warning and lead to unexpected results.
It is generally better practice to go through the setter (self.property = foo) rather than directly accessing the ivar as it is possible that the setter for the property has some behavior you may want and directly accessing it bypasses this. Of course, there are situations where accessing the ivar directly is required, but it is best to go through the property as a default.
Related
This question already has answers here:
iOS: Usage of self and underscore(_) with variable [duplicate]
(3 answers)
Closed 8 years ago.
When I declare an NSString I simply do:
NSString * my_string; (in interface of my .h)
If I want to allow access to this string from other classes I add a property in this way
property (nonatomic, strong) NSString *my_string;
and I write the synthesize
synthesize my_string; (in .m)
Now I have some question about:
If I use a property, must I also use the simple declaration in interface?
If I use my_string as a property, must I always use self. before?
If I use a property, is it necessary to write #synthesize for each? (because I saw that sometimes it's not necessary.
If I use a property, must I also use the simple declaration in interface?
No, generally you just want to use the #property (it will quietly add an instance variable for you).
If I use my_string as a property, must I always use self. before?
You don't need to but you should. Using self. calls the accessor method to get the variable contents. Not using self. accesses the instance variable directly. So, if you add a custom accessor in the future you will need to refactor.
Often you will reuse the same variable multiple times. In this case, call self., but use it to set a local variable that you then use throughout the method (in this way the accessor is only called once).
If I use a property, is it necessary to write #synthesize for each? (because I saw that sometimes it's not necessary.
No, the compiler will add:
#synthesize propertyName = _propertyName;
for you, and that is a good approach to follow (separating the property name from the instance variable name).
NO
NO, using self. will execute accessor method, you can use it with name _my_string and then you'll access the variable directly. If you want a different variable name for your property then you must use synthetize with that name
NO, xcode will synthetize it automatically with the variable named _my_string
It's becoming more and more appropriate to use properties in all cases anymore. You can declare "private" properties inside a header extension inside the .m file if you don't want to expose them to outside classes. Say you have a property called name in the .h file:
#property (nonatomic, strong) NSString *name;
Users of this class can access the name property by saying theVariable.name, inside your .m file you need to access this property with self.name. However you can access the ivar like so:
_name = #"John Smith"
This will skip the property and go directly to the ivar. In this case if you had an overriden setter it won't be called.
You no longer need to synthesize properties. Xcode will automatically provide this:
#synthesize name = _name;
This question already has answers here:
Synthesized property and variable with underscore prefix: what does this mean? [duplicate]
(3 answers)
Closed 9 years ago.
I've been playing with iOS for several months, always use #synthesize to "make setter and getter" of #property. But in some tutorials, I often see #synthesize param = _param, I don't quite get its meaning.
For example: in .h file
#property (nonatomic, retain) NSString *param1;
#property (nonatomic, retain) NSString *param2;
in .m file
#synthesize param1; //this is what I like to do
#synthesize param2 = _param2; // this is what 'experienced' programmer does
From my habit, I can use self.param1, or just param1 to get this instance, is there any difference by the way?
From others, they seem like to use _param2 instead of other approach.
I know it has something to do with getter/setter, but I still not quite clear.
Could someone explain their difference and pros/cons?
Thanks a lot.
When you use
#synthesize param2 = _param2;
means that you are using a different name to access the instance variable directly.
(In new XCode versions, if you dont specify the synthesize yourself XCode writes one for you, same as that one)
If you use:
_param2
You are accessing the instance variable directly.
If you use:
self.param2
You are accessing the variable trough the setter/getter, and those setter/getter are defined using the properties you set.
As a rule of thumb, you want to access you ivar directly in the init methods, and in the rest of the class you use self.
If you want to get more info on this, just follow this link:
Encapsulating data in Objective-C
#synthesize param2 = _param2; Uses another name for the underlying instance variable. The pro is that you don't access the ivar by mistake as easily.
These days you get synthesize automatically and it uses the second variant so just leave out the #synthsize all together and use self.param and _param.
This question already has answers here:
Is there a difference between an "instance variable" and a "property" in Objective-c?
(6 answers)
Closed 9 years ago.
What is the difference between these declarations, lets call them red and orange:
pros, cons?
The red set is properties, and the orange set is instance variables.
A property declaration tells the compiler to define a getter method, and possibly a setter method. (No setter method if the property is readonly.)
In newer versions of Objective C, declaring a property also creates an instance variable that is used to save values for the property. By convention the instance variable has the same name as the property, but with an "_" prefix. There is a way to change the name of the instance variable, but let's ignore that for now.
The property foo:
#property (nonatomic, strong) NSString *foo;
Would have a getter method:
- (NSString *) foo;
and a setter method
- (void) setFoo: (NSString *) foo;
That enables you to use code like this:
NSString *aString = self.foo;
or
NSString *aString = [self foo];
(2 different, equally valid ways of invoking the getter)
And invoking the setter
self.foo = #"a string";
or
[self setFoo: #"a string"];
(2 different, equally valid ways of invoking the setter)
Properties are really useful when you want to create a public interface to get and set values in your class from outside. If you declare a property as "atomic" the compiler adds additional code to the getter and the setter so reads and writes to the property are "thread safe", and can be accessed from background threads.
Before ARC, properties also were a very clean way to manage retains and releases. You declared a property as "retain" and the setter was written to retain the object that was passed in. That's less of an issue in ARC, because the system takes care of retains and releases for you.
It is also possible to write a custom getter or setter method that invokes your own code instead of the compiler-written code. You can use that to do things like log information, send notifications about changes, update labels, etc, etc. You simply add a method body to your .m file that has the same method signature as the getter or setter and the compiler uses that method instead of the automatically generated one.
As I said before, the code:
self.foo = #"a string";
is the same as
[self setFoo: #"a string"];
and invokes the setter method. The setter method sets the internal instance variable _foo.
However, the code
_foo = #"a string";
changes the instance variable directly, without invoking the setter. If you do define a property, you should use it instead of the instance variable.
Objective-c use to be simple...and tedious. You would declare instance variables for a class (the orange) and then you would define (usually) 2 methods for each, one so that an external class could set each instance variable to a new value, and one that returned the ivars value so an external object could read it. Aka, you had to write a getter and setter for each ivar. This was two lines of code in the interface and sometimes around 10 lines of code for the implementation file.
Then came properties, declared with #property. There was much rejoicing and drinking in the streets. These single #property lines told the compiler to write those methods for you, including the correct memory management code and even mutex locking code (depending on what you specified when declaring the #property)
Theres a whole lot of history, but nowadays, with automatic reference counting, it really only makes sense to use #properties in your interface, when you want to make an ivar public, and declare your private ivars in your implementation file.
Lastly, not that #property not only tells the compiler to implement your getter and setter, but it also automatically provides an instance variable with the same name, but prefixed with an underscore (this is only if you have implicit synthesizing of properies enabled...more history)
So, thats the difference. #property tells the compiler to write code for you (essentially). What code it actually writes is modified by all the different ways you can declare a #property.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective-C - When to use 'self'
I needed a variable to be passed from one view to another so I made a property called StringC in the .h and accessed it using self.StringC (that part worked).
I also need some arrays that are accessible throughout the view but I'm using them differently.
For instance I have lvLabelArray and I'm using
self.lvLabelArray=[[NSMutableArray alloc]init];
and then later I'm using
[lvLabelArray addObject:LabelText];
Is there a difference between that and
[self.lvLabelArray addObject:LabelText];
?
Sorry I don't know the terms for those kinds of variables.
There is an important difference there.
self.attribute goes through the object's getter or setter function, as appropriate. That allows you to set up initial values, trigger update messages, or anything else.
Accessing "attribute" directly goes straight to the underlying variable, so you bypass all that. As a result, it's definitely the less-preferable way of working.
A common way of avoiding this confusion, and just plain mistakes, is to rename the underlying variable. Instead of just "#synthesize attribute", use "#synthesize attribute = _attribute". This will create the getter and setter methods as before, but they'll the underlying variable is named "_attribute". That means that trying to use "attribute" without "self" will trigger a compiler error.