What's the meaning of prefix "_" in parameters in Objective-C [duplicate] - ios

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.

Related

Declaration under interface in Objective C

I am studying Big Nerd Ranch's Objective C programming book.
I saw a code like below:
#interface BNREmployee : BNRPerson
{
NSMutableArray *_assets;
}
#property (nonatomic) unsigned int employeeID;
#property (nonatomic) unsigned int officeAlarmCode;
#property (nonatomic) NSDate *hireDate;
#property (nonatomic, copy) NSArray *assets;
-(double)yearsOfEmployment;
-(void)addAsset:(BNRAsset *)a;
-(unsigned int)valueOfAssets;
In this code, why do you declare NSMutableArray *_assets under the interface? How is this different than declaring it as a property, and what purpose does it serve?
Lastly, I see there is a NSArray *assets in a property. Is this basically same as NSMutableArray *_assets?
Here, you're declaring an instance variable named _assets:
#interface BNREmployee : BNRPerson {
NSMutableArray *_assets;
}
You can now use this variable within the implementation of your class:
_assets = #[ #1, #2, #4 ].mutableCopy;
NSLog(#"The Answer is %#.", _assets[0]);
However, instance variables are private in Objective-C, which is good if you do not want anything else to access it. However what if you need other classes to be able to access and/or change assets?
For the most part you will want to use a property iVar.
By using a property we automatically create the setters and getters, meaning this can be overridden for customization and used by other classes (if placed in the header .h file).
#property (nonatomic, assign) NSMutableArray *assets;
NSMutableArray is just the mutable (editable) counterpart to NSArray, it means we can modify the values of the array by inserting new ones, deleting old ones and moving the indexes around.
I'm not sure why they did that but as a general good practice, you shouldn't do that yourself. The header file should be reserved for the public interface of the class. Only put things in there that callers and users of that class actually need to see, which will generally be properties, methods, and perhaps extern constants.
Then the question becomes in the implementation whether to use a property or a regular instance variable. This is largely preference based. Some people declare properties for everything and don't use plain ivars at all. Others use ivars for everything and only properties when they want to declare a custom setter/getter for the variable in question. I am in the latter camp but it is arguable that is clearer and easier to read if everything is just a property.
edit
I misread the code. What I say above stands normally, but what they are doing there is exposing an API that is different than the underlying data. Editing my answer now.
When you declare a property without a custom #synthesize and without having overridden both the setter and getter if they are applicable, an underlying variable is created with the underscore in front. What they are doing here is returning an NSArray in the public API to ensure the internal variable is not modified while internally using an NSMutableArray.
I would say that in general though, that variable declaration (NSMutableArray *_assets;) should still go in the implementation file. The caller should probably not need to know that it is mutable under the hood.
There are actually a lot of existing questions touching upon this already. Here is a search query with a number of them:
https://stackoverflow.com/search?q=mutable+ivar+immutable+property
The key idea is that instance variable has a different type than the property declaration: it is mutable, whereas the property declaration is immutable.

IOS: property and self [duplicate]

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;

Variables in .h-file as opposed to .m-file in objective-C [duplicate]

This question already has answers here:
Declaration/definition of variables locations in ObjectiveC?
(4 answers)
Closed 9 years ago.
I fairly new to IOS programming, and came over this the other day:
say you have a TestVC.h file:
#interface TestVC : UIViewController
#property (strong, nonatomic) IBOutlet UIProgressView *progress;
#end
and in TestVC.m file (at the top):
#interface TestVC ()
#property (strong, nonatomic) NSArray *levels;
#end
When you use a variable from .h-file, you'd say self.progress
If you use a variable from the .m-file, it's _levels
What is the difference?
When you use a variable from .h-file, you'd say self.progress
If you use a variable from the .m-file, it's _levels
There is no difference. self.progress and _progress and self.levels and _levels are all perfectly functional.
However, the _ syntax is a tiny bit faster and the self. syntax is the proper way to do it except in a few cases where it's not. There are times when using _ will cause serious problems that are solved by using self.. And there are times when self. will cause problems.
Basically _ is accessing the raw memory address directly, and self. is accessing it "properly" using the objective-c language.
The difference between declaring a variable in *.m vs *.h is that the one in *.m is hidden, so nothing else in your source code can see that it exists. It is there but you will get a compiler warning that it doesn't exist. When it compiles it will work though, because really it does exist.
Basically declaring variables in *.m is a way of saying "this thing is here but I don't want anything outside this file to ever use it". It's purely cosmetic, has no impact on the how the app functions.
As a new Obj-C programmer, you should always use self.levels. Any time you see sample code using _levels I would change it to self.levels. If you run into problems... ask here to see if you've found a case where _levels should be used.
They can be used in either format regardless of their being declared in the .h or .m files.
Best practice is to use the getter/setter "self." format everywhere with the possible exception of init and dealloc methods where the "_" direct access method is generally deemed to be a better choice.

Synthesizing CGFloat property in iOS

I declared a property as below. From my readings on the web, it is not clear if I should also synthesize as below. I have seen supporting blog posts for two different approaches.
#property (assign, nonatomic) CGFloat someFloat;
Then in the implementation:
#synthesize someFloat = _someFloat;
I have also seen in some cases:
#synthesize someFloat;
From readings, I understand that "someFloat" is a property name, and "_someFloat" is created through the synthesis. So I am under the impression that the first way is correct. However, I have used the second approach without problems. And I have seen the second approach in other code and blogs.
Can someone tell me what is the correct way and why?
In general, you no longer need to manually write #synthesize anymore. In your example, if you write
#property (assign, nonatomic) CGFloat someFloat;
The compiler will automatically synthesize it for you, which would be equivalent to you writing
#synthesize someFloat = _someFloat;
Hence, you would be able to access the property through self.someFloat or access the ivar within the implementation file by using _someFloat.
If, however, you manually synthesize it like
#synthesize someFloat;
The compiler automatically creates a backing ivar titled someFloat... thereby, you would still be able to access the variable through the getter self.someFloat (that is, equivalent to [self someFloat] call).
Or, you could access the ivar by simply using someFloat somewhere within the implementation...
In general, it's not recommended to synthesize like this because it's quite easy to accidentally use the ivar when you meant to access the variable using the getter.
EXCEPTION TO THE RULE
The compiler still gets confused with synthesizing variables sometimes, however, in certain instances. For example, if you have a class that is a subclass of NSManagedObject, then you still need to write the #synthesize manually (assuming, of course, you actually want to synthesize the property... you likely don't though...).
The reason for this is two-fold: (1) the compiler doesn't seem to understand these properties very well yet (or at least it doesn't in the cases I've worked with), and (2) many times, you actually DON'T want to #synthesize properties on an NSManagedObject subclass... rather, you want them to be #dynamic instead (so the getter/setter will be generated at runtime, per requirements of NSManagedObject subclass magic).
Just skip the #synthesize statement, the compiler will generate the same thing as if you had:
#synthesize someFloat = _someFloat;

Should I declare variables in interface or using property in objective-c arc?

approach 1:
#interface MyController : UIViewController {
UILabel *myText;
}
#property (nonatomic, strong) UILabel *myText;
approach 2:
#interface MyController : UIViewController
#property (nonatomic, strong) UILabel *myText;
approach 3:
#interface MyController : UIViewController {
UILabel *myText;
}
I have read some articles talking about this kind of stuff but I still do not really realize which approach I have to adopt.
I also found that someone said approach 1 is a old way so I would like to know the best practice for ios sdk 6 using ARC.
I know that declaring variables using property is a easy way for generating getter and setter and someone suggested using it. However, I would like to ask in case a variable is not for calling by another class, is it necessary for the variable using property? and set it as private variable inside the interface? Or is it better for a variable only declaring inside the interface? I would like to learn the best practice so please forgive me if this is a silly question.
Moreover, some developers write #synthesize in this way
#synthesize myText=_myText;
but some write this:
#synthesize myText;
I would also want to know the difference and which one is preferable?
Thank you very much!
The most modern way1:
whenever possible, declare properties
don't declare iVars separately 2
don't #synthesize 3
locate as few properties as possible in you .h file 4
locate as many properties as possible in a class extension in your .m file 5
1 As of Xcode 4.5.2. Most of this applies back to 4.4, some of it won't compile on 4.2 (the last version available under Snow Leopard). This is preprocessor stuff, so it is all compatible back at least to iOS5 (I haven't tested on iOS4 but that should also be OK).
2 There is no point in declaring an iVar as well as a property. I am sure there are a few obscure cases where you would want to declare iVars instead of properties but I can't think of any.
3 Xcode will create an iVar with the same name as the property, preceded by an _underscore. If you (rarely) need some other kind of behaviour, you can manually #synthesize property = someOtherName. #vikingosegundo links us to this article on dynamic ivars, which is a use case for #synthesize. #RobNapier comments that you do need to #synthesize iVar = _iVar (bizarrely) if you are creating your own getters (readonly) and setters (read/write) for a property, as in this case the preprocessor will not generate the iVar for you.
4 The general rule with your interface: keep it as empty as possible. You don't actually need to declare your methods now at all, if they are for private use. If you can get the code to work without an interface declaration, that's the way to go.
5 This is an #interface block in your .m file, placed above your #implementation:
#TestClass.m
#interface TestClass()
//private property declarations here
#end
#implementation TestClass
...
You may also want to use #synthesize if you like a nice table of contents of your #synthesized properties that you can refer to and comment for clarity and organization.
Also, an #synthesize allows you to set a breakpoint on the property and trap when its value is changed.
When the compiler does everything for you, you end up being distanced from what is really happening and ignorant to it. However, not having to type out everything yourself all the time is also nice.

Resources