Question about #synthesize - objective-c

When you create a new application from Xcode that embed CoreData you got those lines in the implementation file of the delegate:
#synthesize window=_window;
#synthesize managedObjectContext=__managedObjectContext;
What are the differences between using only a underscore or double it? What's the difference on writing only:
#synthesize window;

A leading underscore is a naming convention helpful to differentiate between instance variables and accessors. For the compiler it is just a common ivar rename.
Consider the difference (non ARC code):
self.date = [NSDate date]; // OK, the setter releases the old value first
date = [NSDate date]; // WRONG, skipping the setter causes a memory leak
_date = [NSDate date]; // WRONG but easier to see it's not a local variable
With ARC variables won't be leaked, but it is still wrong to skip the #property attributes:
#property (copy) string;
// ...
self.string = someString; // OK, string is copied
string = someString; // WRONG string is retained but not copied
_string = someString; // WRONG but hopefully easier to see
Even worst, some APIs like Core Data rely on KVC notifications to perform lazy loading. If you accidentally skip the accessors, your data will come back as nil.
This is the reason you often find #synthesize var=_var, which makes
self.var an accessor reference (invoking setters and getters),
_var a direct access reference (skipping setters and getters),
and var an invalid reference.
Given that #synthesize var=_var is autogenerated by LLVM 4.0 when #synthesize is omitted, you can consider this the default naming convention in Objective-C.
Keep reading for details...
Modern runtime
In Objective-C 2.0 you declare variables like this:
#interface User : NSObject
#property (nonatomic, assign) NSInteger age;
#end
#implementation User {
#synthesize age; // this line can be omitted since LLVM 4.0
#end
which is translated by the compiler as follows:
#interface User : NSObject {
NSInteger age;
}
#end
#implementation User
-(void)setAge:(NSInteger)newAge {
age=newAge;
}
-(void)age {
return age;
}
#end
If you prefer to use the underscore convention just add the following:
#synthesize age=_age;
That's all you need because with the modern runtime, if you do not provide an instance variable, the compiler adds one for you. Here is the code that gets compiled:
#interface User : NSObject {
NSInteger _age;
}
#end
#implementation User
-(void)setAge:(NSInteger)newAge {
_age=newAge;
}
-(void)age {
return _age;
}
#end
What happens if you add both the ivar and the #property? If the variable has the same name and type, the compiler uses it instead generating a new variable. Quoting The Objective-C Programming Language > Declared Properties > Property Implementation Directives:
There are differences in the behavior of accessor synthesis that
depend on the runtime:
For the modern runtimes, instance variables are synthesized as needed. If an instance variable of the same name already exists, it is
used.
For the legacy runtimes, instance variables must already be declared in the #interface block of the current class. If an instance
variable of the same name as the property exists, and if its type is
compatible with the property’s type, it is used —otherwise, you get a
compiler error.
Legacy runtime
But if you need to support the legacy runtime you must either provide an instance variable with the same name and compatible type of the property or specify another existing instance variable in the #synthesize statement.
So the legacy code without underscores would be:
#interface User : NSObject {
NSInteger age;
}
#property (nonatomic, assign) NSInteger age;
#end
#implementation User
#synthesize age;
#end
Or if you prefer the underscore convention:
#interface User : NSObject {
NSInteger _age;
}
#property (nonatomic, assign) NSInteger age;
#end
#implementation User
#synthesize age = _age;
#end
What is the best way?
Apple discourages the use of underscore in methods, but not on variables!.
Apple on methods: Coding Guidelines for Cocoa: Typographic Conventions:
Avoid the use of the underscore
character as a prefix meaning private,
especially in methods. Apple reserves
the use of this convention. Use by
third parties could result in
name-space collisions; they might
unwittingly override an existing
private method with one of their own,
with disastrous consequences.
Apple on variables: Declared Properties and Instance Variables
Make sure the name of the instance variable concisely describes the
attribute stored. Usually, you should not access instance variables
directly, instead you should use accessor methods (you do access
instance variables directly in init and dealloc methods). To help to
signal this, prefix instance variable names with an underscore (_),
for example: #implementation MyClass { BOOL _showsTitle; }
ISO/IEC 9899 7.1.3 Reserved identifiers (aka C99):
All identifiers that begin with an underscore and either an uppercase
letter or another underscore are
always reserved for any use.
All
identifiers that begin with an
underscore are always reserved for use
as identifiers with file scope in both
the ordinary and tag name spaces.
On top of that, double leading underscore is traditionally reserved for the vendor of the preprocessor / compiler / library. This avoids the case where you use __block somewhere in your code, and Apple introduces that as a new non-standard keyword.
Google Objective-C Style guide:
Variable Names Variables names start
with a lowercase and use mixed case to
delimit words. Class member variables
have trailing underscores. For
example: myLocalVariable,
myInstanceVariable_. Members used for
KVO/KVC bindings may begin with a
leading underscore iff use of
Objective-C 2.0's #property isn't
allowed.
Google's trailing underscore doesn't force you to type one more character before Xcode fires the autocomplete, but you'll realize it is an instance variable slower if the underscore is a suffix.
Leading underscore is also discouraged in C++ (see What are the rules about using an underscore in a C++ identifier?) and Core Data properties (try adding a leading underscore in the model and you'll get "Name must begin with a letter").
Whatever you chose, collisions are unlikely to happen, and if they do, you'll get a warning from the compiler. When in doubt, use the default LLVM way: #synthesize var=_var;
I own an edit of this post to reading A Motivation for ivar decorations by Mark Dalrymple. You may want to check it out.

You can use just
#synthesize window;
if your instance variable is named 'window', however, some people use a naming convention of prefixing all instance variables with underscore, but still prefer to have their getters and setters without the underscore prefix, thats what the 'window=_window' means.
I don't know what double underscore means, but I suspect it's also a matter of a naming convention.

Related

Simple Class Extension / Inheritance Clarification

I've been writing Objective-C for a few years now, and decided to go back and learn the very basics to help me write even better code. I'm trying to learn all about instance variables, inheritance and class extensions. I've been reading up on all three, but there is one thing that boggles my mind. I have a simple app that contains 2 classes, Person, Male (inherits from Person), and of course Main (which imports the Male class, therefore being able to access the instance variables found in both Person and Male).
The code is simple, and for the sake of space I won't post all of it. Basically Main takes these variables and plays around with them. This is the part that is boggling my mind:
#interface Person : NSObject {
float heightInMeters;
int weightInKilos;
}
#property float heightInMeters;
#property int weightInKilos;
#end
When I delete the brackets and variable declarations, leaving it like this:
#interface Person : NSObject
#property float heightInMeters;
#property int weightInKilos;
#end
The code still inherits and executes just fine.
1. What is the point of even declaring them there in the first place if we can just create two properties?
2. why create two instance variables AND properties to correspond with them?
3. I know that we can declare the variables in the .m instead to keep them private to the class and everything that subclasses it. like this:
#implementation Person {
float heightInMeters;
int weightInKilos;
}
What is the difference here? I feel like I'm missing a lot of basics. Is there a simplistic way of putting this all in perspective?
When you declare a #property, the compiler will automatically synthesize the variable prefixed with an underscore, a getter method, and a setter method.
#interface MyClass ()
#property(strong, nonatomic) NSString *myString;
#end
In this example the compiler would syhtnesize the variable as _myString, the getter as
-(NSString *)myString
and the setter as
-(void)setMyString:(NSString *)string
The keywords after "#property" (strong, nonatomic) define the property's attributes. strong, the default, implies ownership, meaning that in this case MyClass instances will essentially be responsible for the retain/release of their respective myString objects. nonatomic means the variable is not guaranteed to always be a valid value in a multithreaded environment, for example if the getter is called at the same time as the setter.
Additionally, the compiler will treat dot syntax used to retrieve/set instance variables as calls to the appropriate getter/setter methods. Therefore, given an instance of MyClass
MyClass *exampleClass = [[MyClass alloc] init];
Both of the following are equivalent statements:
NSString *string1 = example.myString; // dot syntax
NSString *string1 = [example myString]; // explicit call to the getter method
For further reading, take a look at Apple's Programming with Objective-C Guide.
As for your specific questions:
1. What is the point of even declaring them there in the first place if we can just create two properties?
It's actually not a good idea to declare variables explicitly as public variables in your MyClass.h file (or in most other cases). Instead, declaring them as properties automatically creates a private variable (and accessor methods), making adhering to OOP best practices a little easier. So there is no point in declaring
// MyClass.h
#interface MyClass : NSObject {
NSString *myString // public variables not good
}
Also because of what I stated above regarding dot syntax, if you use self.myString internally in MyClass.m or instanceOfMyClass.myString externally, the public variable myString will never even be touched because the synthesized variable is named _myString.
2. Why create two instance variables AND properties to correspond with them?
See above--you don't need two instance variables, only one.
3. I know that we can declare the variables in the .m instead to keep them private to the class and everything that subclasses it. What is the difference here? I feel like I'm missing a lot of basics. Is there a simplistic way of putting this all in perspective?
If you declare your variables privately in the #implementation part of your .m file, the compiler won't be able to help you by synthesizing the getters and setters. Even as private methods, getters and setters can help reduce complexity in your code, for example checking for the validity of variable values. (Note: you can override accessor methods.)
// MyClass.m
#interface MyClass () // private interface
#property(nonatomic, strong) NSString *myString;
#end
#implementation MyClass {
// no more need for private variables!
// compiler will synthesize NSString *_myString and accessors
}
-(void)setMyString:(NSString *)string { // overwrite setter
// no empty strings allowed in our object (for the sake of example)
NSAssert([string length] > 0, #"String must not be empty");
// assign private instance variable in setter
_myString = string;
}
#end
This way, even when you subclass MyClass, the subclass will inherit the getter and setter methods that were synthesized for us by the compiler.

Why we are declaring same thing two time in .h file in iOS [duplicate]

I've seen in a few iPhone examples that attributes have used an underscore _ in front of the variable. Does anyone know what this means? Or how it works?
An interface file I'm using looks like:
#interface MissionCell : UITableViewCell {
Mission *_mission;
UILabel *_missionName;
}
#property (nonatomic, retain) UILabel *missionName;
- (Mission *)mission;
I'm not sure exactly what the above does but when I try to set the mission name like:
aMission.missionName = missionName;
I get the error:
request for member 'missionName' in something not a structure or union
If you use the underscore prefix for your ivars (which is nothing more than a common convention, but a useful one), then you need to do 1 extra thing so the auto-generated accessor (for the property) knows which ivar to use. Specifically, in your implementation file, your synthesize should look like this:
#synthesize missionName = _missionName;
More generically, this is:
#synthesize propertyName = _ivarName;
It's just a convention for readability, it doesn't do anything special to the compiler. You'll see people use it on private instance variables and method names. Apple actually recommends not using the underscore (if you're not being careful you could override something in your superclass), but you shouldn't feel bad about ignoring that advice. :)
The only useful purpose I have seen is to differentiate between local variables and member variables as stated above, but it is not a necessary convention. When paired with a #property, it increases verbosity of synthesize statements – #synthesize missionName = _missionName;, and is ugly everywhere.
Instead of using the underscore, just use descriptive variable names within methods that do not conflict. When they must conflict, the variable name within the method should suffer an underscore, not the member variable that may be used by multiple methods. The only common place this is useful is in a setter or in an init method. In addition, it will make the #synthesize statement more concise.
-(void)setMyString:(NSString*)_myString
{
myString = _myString;
}
Edit:
With the latest compiler feature of auto-synthesis, I now use underscore for the ivar (on the rare occasion that I need to use an ivar to match what auto-synthesis does.
It doesn't really mean anything, it's just a convention some people use to differentiate member variables from local variables.
As for the error, it sounds like aMission has the wrong type. What it its declaration?
This is only for the naming convention of synthesize properties.
When you synthesize variables in the .m file, Xcode will automatically provide you _variable intelligence.
Having an underscore not only makes it possible to resolve your ivars without resorting to using self.member syntax but it makes your code more readable since you know when a variable is an ivar (because of its underscore prefix) or a member argument (no underscore).
Example:
- (void) displayImage: (UIImage *) image {
if (image != nil) {
// Display the passed image...
[_imageView setImage: image];
} else {
// fall back on the default image...
[_imageView setImage: _image];
}
}
This seems to be the "master" item for questions about self.variableName vs. _variablename. What threw me for a loop was that in the .h, I had:
...
#interface myClass : parentClass {
className *variableName; // Note lack of _
}
#property (strong, nonatomic) className *variableName;
...
This leads to self.variableName and _variableName being two distinct variables in the .m. What I needed was:
...
#interface myClass : parentClass {
className *_variableName; // Note presence of _
}
#property (strong, nonatomic) className *variableName;
...
Then, in the class' .m, self.variableName and _variableName are equivalent.
What I'm still not clear on is why many examples still work, even tough this is not done.
Ray
instead of underscore you can use self.variable name or you can synthesise the variable to use the variable or outlet without underscore .
Missing from the other answers is that using _variable prevents you from absentmindedly typing variable and accessing the ivar rather than the (presumedly intended) property.
The compiler will force you to use either self.variable or _variable. Using underscores makes it impossible to type variable, which reduces programmer errors.
- (void)fooMethod {
// ERROR - "Use of undeclared identifier 'foo', did you mean '_foo'?"
foo = #1;
// So instead you must specifically choose to use the property or the ivar:
// Property
self.foo = #1;
// Ivar
_foo = #1;
}

What qualifier should I use to declare a block as an ivar?

Example:
typedef void(^responseBlock)(NSDictionary*, NSError *);
#interface MyClass : NSObject
{
[??] responseBlock responseHandler;
}
What qualifier should I put in the [??] brackets?
I've read that blocks as properties should be setup with the copy qualifier...but in this case I don't need the block exposed as a property. I simply want it to remain an ivar but how can I specify copy? And also, without specifying anything what is the default qualifier used? Is it __strong as in the case with everything else?
I'm using ARC on ios5.
Yes, Blocks are objects in ObjC, so __strong is the appropriate qualifier. Since that's the default, you can in fact leave it off.
There's no way for you to specify that the Block be copied on assignment without a property -- that will be your responsibility (responseHandler = [someBlock copy];). You could declare a property that's only visible to this class itself (not available to other code) by putting a class extension in your .m file:
#interface MyClass ()
#property (copy) responseBlock responseHandler;
#end
This (upon being synthesized) will give you the usual accessor methods, which will take care of the copy for you when you use them.
Also be aware that it's possible (and now the recommended procedure) to declare instance variables in the #implementation block. It sounds like you want this to be a private attribute (no property access), and the ivars declared there can't be seen by any other code. (Of course you don't need to do this if you're using a property; #synthesize will create the ivar for you.)
#implementation MyClass
{
responseBlock responseHandler;
}
// Continue with implementation as usual

Why put underscore "_" before variable names in Objective C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
In objective C I am seeing lots of code with a underscore before variable names e.g _someVariable
why is that? also how to you write accessors i.e get and set method for such a variable.
The underscores are often used to show that the variables are instance variables. It is not really necessary, as ivars can have the same name as their properties and their accessors.
Example:
#interface MyClass : NSObject {
NSString *_myIVar; // can be omitted, see rest of text
}
// accessors, first one is getter, second one is setter
- (NSString *) myIVar; // can be omitted, see rest of text
- (void) setMyIVar: (NSString *) value; // can be omitted, see rest of text
// other methods
#property (nonatomic, copy) NSString *myIVar;
#end
Now, instead of declaring and coding the accessors myIVar and setMyIVar: yourself, you can let the compiler do that. In newer versions, you don't even have to declare myIVar in the interface. You just declare the property and let the compiler synthesize the rest for you. In the .m file, you do:
#implementation MyClass
#synthesize myIVar; // generates methods myIVar and setMyIVar: for you,
// with proper code.
// also generates the instance variable myIVar
// etc...
#end
Be sure to finalize the string:
- (void) dealloc {
[myIVar release];
[super dealloc];
}
FWIW, if you want to do more than the default implementation of the getter or setter do, you can still code one or both of them yourself, but then you'll have to take care of memory management too. In that case, the compiler will not generate that particular accessor anymore (but if only one is done manually, the other will still be generated).
You access the properties as
myString = self.myIVar;
or, from another class:
theString = otherClass.myIVar;
and
otherClass.myIVar = #"Hello, world!";
In MyClass, if you omit self., you get the bare ivar. This should generally only be used in the initializers and in dealloc.
Don't do it.
Single leading underscores are an Apple internal coding convention. They do it so that their ivar names won't collide with yours. If you want to use a prefix on your ivar names, use anything but a single underscore.
this is a naming convention normally used for c++ to define instance variable which are private
like in a class u may have
private:
int __x;
public:
int GetX()
{
return this.__x;
}
this is a naming convention, i was forced to use in c++. However my teacher never told us the name of the naming convention. But i feel this is helpfull and readable specially when u are not using java naming conventions.

Do I need to declare a property in the instance variables section, too? What do I gain?

I read some tutorials here about properties ,but i still have some doubts to clarify, is there a difference between
#interface MyClass : NSObject {
}
#property(nonatomic,retain) NSString *temp;
#end
AND
#interface MyClass : NSObject {
NSString *temp;
}
#property(nonatomic,retain) NSString *temp;
#end
The difference is that in the first version, the compiler will automatically create an instance variable (IIRC, it will be named _temp but I don't know for sure). This is only supported on iOS and Mac 64 bit.
In the second example, you provide the variable.
There's actually a way to tell the compiler which variable to use for the property, which I use a lot:
#interface MyClass : NSObject {
NSString *temp_;
}
#property(nonatomic,retain) NSString *temp;
#end
#implementation MyClass
#synthesize temp = temp_;
#end
This way the variable and the property have different names and you can't confuse them (e.g. by forgetting to prefix self.).
Minor side-note: it's often desirable to use copy instead of retain for NSString *, since you might assign an NSMutableString * to the property. Now if you would change that mutable string unexpected things might happen.
Does the first one even work? If there is no instance variable its a bit hard to have a property to access it.
#properties are meant for you, so you can be lazy, they write the following 2 methods for you ( if not set to readonly ):
- (void)setYourVariable:(id)new;
- (id)yourVariable;
it also allows you to use "someClass.itsVariable;" instead of "[someClass itsVariable];"
Another thing, when you create your header files make sure that the biggest variables ( like pointers ) are on the top and the smallest on the bottom, this saves ram.
thus:
NSObject *someObject;
NSObject *someOtherObject;
int anInt;
short aShort;
BOOL fakeBool;
instead of:
BOOL fakeBool;
NSObject *someObject;
short aShort;
NSObject *someOtherObject;
int anInt;
This has to do with the compiler, you can check this by using sizeof()
In the modern runtime (Objective-C 2.0) it is the same because the compiler will generate the variable for you. See Question about #synthesize
Quoting The Objective-C Programming Language > Declared Properties > Property Implementation Directives:
There are differences in the behavior of accessor synthesis that
depend on the runtime:
For the legacy runtimes, instance variables must already be declared in the #interface block of the current class. If an instance
variable of the same name as the property exists, and if its type is
compatible with the property’s type, it is used—otherwise, you get a
compiler error.
For the modern runtimes, instance variables are synthesized as needed. If an instance variable of the same name already exists, it is
used.
The practical difference that I've found is that the debugger doesn't appear to show you the value of properties, just instance variables.
Therefore, your first example, which (assuming you use the #synthesize directive to create your getter/setter) automatically creates the ivar, will not have a value that you can easily retrieve during debug. You'll end up having to send a lot of NSLog messages, rather than just looking at the values while stepping through your code.
As an aside, which seems to relate to this topic, I typically prepend my ivars with "iv" and change my color settings in XCode preferences so that I'm never unsure whether I'm accessing a property or an ivar.
Example
#interface MyClass : NSObject {
NSString *ivName;
NSString *ivTitle;
}
#property (nonatomic, copy) NSString *Name;
#property (nonatomic, copy) NSString *Title;
#end
Now, this then requires a small trick (to tie the two together) when synthesizing the properties, which I show below:
#implementation MyClass
#synthesize Name = ivName;
#synthesize Title = ivTitle;
This way, it's always very easy for me to know exactly what's going on at a glance. Yes, context can also tell you whether you're accessing an ivar/property, but why not make it easier?