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;
Related
I am so confused between self and underscore to access the property in Objective c, whenever we create property, its getter-setter automatically generated. So we can access the same property with self.property and same as _property. In my opinion, there shoulb be some difference which i am not getting. PLease tell me with examples.
The underbar (underscore) version is the actual instance variable, and should not be referenced directly. You should always go via the property name, which will ensure that any getter/setter actions are honoured.
So if you code _property = 4, you have directly set the variable. If you code self.property = 4, you are effectively making the method call [self setProperty:4], which will go via the setter (which might do something such as enforce property having a max value of 3, or updating the UI to reflect the new value, for example).
Edit: I though it was worth mentioning that the setter (setProperty) will issue a _property = 4 internally to actually set the instance variable.
when you are using the self.XX, you access the property via the setter or getter.
when you are using the _XX, you access the property directly skip the setter or getter.
Let's say you have a property defined as follows:
#property (nonatomic,strong) NSString* name;
The getters and setters of the name property are automatically generated for you.Now, the difference between using underscore and self is that:
self.name =#"someName"; // this uses a setter method generated for you.
_name = #"someName"; // this accesses the name property directly.
The same applies for getting the name property;
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.
I see someone writes codes like this
#interface SomeClass:<NSObject>{
NSString * _iVar;
}
#property(nonatomic,retain)NSString *iVar;
and in implement file
#synthesize iVar = _iVar;
But I always like write codes like this:
#interface SomeClass:<NSObject>
#property(nonatomic,retain)NSString *iVar;
and in implement file
#synthesize iVar = _iVar;
They all works fine, and I can use an instance someClass to get iVar "someClass.ivar".I just know why?
You now don't even have to synthesize the iVars anymore. The latest Xcode will automatically create a backing instance variable for each property, with the property name prefixed with an underscore.
In Objective-C when you are using anything via "." (dot syntax), it is accessing property. You have declared and synthesize a property with name iVar, so you can access it with someClass.iVar.
When you are declaring a property, a variable is automatically created with it. So, even if you do not create a variable, it will be there.
To avoid ambiguity, people are creating properties and iVar with different names. So, they can identify if the variable is being used or a property is being used. In that case people let the compiler know that a particular variable is associated with a property by low way:
#synthesize iVar = _iVar;
If you want access variable directly outside the class instead of property, you should use "->" (arrow syntax).
Why must I define variables twice in the header file? What differences are there between these variables?
The first definition is here:
#interface MyController: UIViewController
{
NSInteger selectedIndex;
}
The second definition is here:
#property (nonatomic) NSInteger selectedIndex;
What you're seeing was required in earlier versions of Objective-C,
but isn't any more.
In the first versions of Objective-C used by NeXT up until the new
runtime was introduced (with Objective-C 2.0 on Mac OS X), all
instance variables had to be declared as part of the class's structure
in its #interface. The reason was that if you subclassed a class,
the compiler needed to know the instance variable layout of the class
so it could see at what offset to put the subclass's instance
variables.
When properties were introduced, synthesized properties had to be
"backed" by an instance variable in the class's structure. Therefore
you had to declare both an instance variable and the property.
All of the above is no longer true. Newer Objective-C is less fragile
in the way it looks up instance variable offsets, which has meant a
few changes:
not all instance variables need to be in the #interface. They can now be defined in the #implementation: though not in categories due
to the possibilities of clashing and other issues.
instance variables for synthesized properties can be inferred and created based on the property definition.
you can programmatically add instance variables to classes you're creating at runtime (only before you've registered the class as
available to the system).
So, to reiterate, you only needed to declare both the instance
variable and a synthesized property in older versions of the
Objective-C language. What you're seeing is redundant and should not
be considered a "best practice".
[Source]
As others have pointed out, it is no longer necessary to declare a backing instance variable for a synthesized property in the header.
To make this a bit clearer though: What you're seeing are not two declarations of the same variable, it is one declaration of the variable and one declaration of the property.
A property is basically a set of methods (in this case selectedIndex and setSelectedIndex:) that are typically used to access instance variables. There is a difference between a property and an instance variable. The property's setter/getter could do more than just set the variable, in your example, it could also e.g. update the UI to reflect the change of the selected index or the getter could infer the index from some other variable (in this case, there might be a selection index path), etc.
Synthesizing a property simply frees you of implementing those methods yourself and provides you with default implementations that simply set the variable, but you could also implement selectedIndex and setSelectedIndex: yourself just like any other method in which case you might either need the instance variable itself or omit it altogether (in case of an inferred property).
In modern runtime you do NOT need to declare them twice. Just use:
In you .h
#property (nonatomic) NSInteger selectedIndex;
The part between the {} is the declaration of the iVar. And with your #property you declare getter and setters. In modern runtime if you just use the code above you say basicly the same (your iVar is now _selectedIndex).