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):
With ARC variables won’t be leaked, but it is still wrong to skip the @property attributes:
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 makesself.varan accessor reference (invoking setters and getters),_vara direct access reference (skipping setters and getters),varan invalid reference.Given that
@synthesize var=_varis autogenerated by LLVM 4.0 when@synthesizeis 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:
which is translated by the compiler as follows:
If you prefer to use the underscore convention just add the following:
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:
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:
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:
Or if you prefer the underscore convention:
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:
Apple on variables: Declared Properties and Instance Variables
ISO/IEC 9899 7.1.3 Reserved identifiers (aka C99):
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
__blocksomewhere in your code, and Apple introduces that as a new non-standard keyword.Google Objective-C Style guide:
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.