Objective-C: Xcode automatically recognizes ' = _property ": is this #synthesize created variable name? - objective-c

When you declare a #property and #synthesize it, it is considered good practice to use:
#synthesize myProperty = _myProperty;
I've noticed that Xcode will autocomplete the ivar name _myProperty for you, even though it hasn't yet been used in the source code.
Is this because the ivar #synthesize creates automatically defaults to the name _myProperty? Or merely because Xcode supports this common convention with an autocompletion for it?
Thanks.
EDIT: I'm not looking for reasons why this is good practice; I'm already aware of those and have used this convention for a while. I want to understand the internals, thus am asking whether this is a hard-coded auto-completion rule to satisfy a convention, or whether it's standard auto-completion and in fact the Objective-C specification dictates that an ivar generated by #synthesize must have the form _myProperty, thus after behind the scenes generation of the ivar, auto-completion is aware of its existence. Thanks!

I think the autocompletion is an IDE convenience rather than a result of the runtime. My logic for this is that the following appears to be valid:
#interface SomeClass()
#property (nonatomic, assign) int unpublishedInstanceVariable;
#end
#implementation SomeClass
#synthesize unpublishedInstanceVariable;
- (void)someMethod
{
unpublishedInstanceVariable = 3; // not calling the setter
}
#end

hard-coded auto-completion rule to satisfy the convention
If you don't specify an iVar name explicitly, it will be called myProperty. The autocomplete doesn't have anything to do with the compiler, it's just Xcode being extra helpful.

As of Xcode 4.4, there is a new twist to the tail (sic).
We are now allowed to skip the #synthesize altogether. In this case, the compiler automatically generates the #synthesize foo = _foo; declaration for us, with the instance variable name prefixed with an underscore.
#interface Foo : NSObject
#property (nonatomic, copy) NSString *foo;
#end
#implementation Foo
- (void)bar {
NSLog(#"%#", _foo); // this Works!
}
#end
However, if we do have an explicit #synthesize statement but do not specify the name of the instance variable, then the default name of the instance variable is the same as that of the property i.e. not prefixed with an underscore, in which case #Tommy's answer still holds.
It'd be great if someone could point out the links to official Apple Docs that document this behaviour.
Update
My findings were spot on. This behaviour (of #synthesize being the default, and creating a backing underscore prefixed instance variable in the absence of an explicit synthesize etc.) was publicly announced in WWDC 2012 Session 405 - Modern Objective-C.

wrt this part of your question:
whether ... in fact the Objective-C
specification dictates that an ivar generated by #synthesize must have
the form _myProperty,
You can name your ivar anything you want. From the docs:
You can use the form property=ivar to indicate that a particular
instance variable should be used for the property, for example:
#synthesize firstName, lastName, age=yearsOld;
This specifies that the accessor methods for firstName, lastName, and age should be
synthesized and that the property age is represented by the instance
variable yearsOld.
Also,
The #synthesize directive also synthesizes an appropriate instance variable if it is not otherwise declared.

Related

What is the difference between these three ways to declare a variable?

I am learning Objective-C and was just curious. I can create an object of a NSString in these places, and please provide any others. To me they all do the same thing. I don't know what is the difference is between them. Where is it stored? From where can I access it? What are the advantages?
1)
// .h
#interface ...
#property (strong,nonatomic) NSString *text;
#end
2)
// .h
#interface ... {
NSString *text
}
#end
3)
// .m
#interface ... ()
#property (strong,nonatomic) NSString *text;
#end
First and foremost, my answer is based on the latest Clang compiler, older versions worked slightly different.
So, you're not creating an object in neither. You're not even declaring an object in two of them.
In the first case, you're actually telling the compiler that you need to expose a property called text of type NSString. What the compiler does, is declaring an instance variable for you _text (which you can access without a problem by the way) and the methods needed to get and set that instance variable. As you can see the storage is still internal, you just have getters and setters set for you.
In the second case you're actually declaring an instance variable (ivar) yourself, just as the compiler does with _text. It's accustom to prefix it with _. The storage is still internal. On top of that, you can't access your ivar from outside, since it has no getter or setter and the implicit declaration is #private.
In the third case, you create an anonymous category (thus the empty parentheses) which adds a property to your class. Storage for this is a little bit harder/longer to explain, if you are curious about it, you can search up the Apple docs, see what a category is and so on. You can only access your property from within your class in this case, which makes it somehow redundant (the getters and setters), you could have declared it as an ivar.
You can also declare your ivars like this:
#interface GenericViewController : UIViewController{
NSString * text;
}
#end
#implementation GenericViewController{
NSString * text;
}
#end
Both of the above have local storage and private visibility (can't be accessed from outside). The difference between the two is that instance variables declared in the implementation are implicitly hidden and the visibility cannot be changed with #public, #protected and #private. If you use those directives you won't get compiler errors but are ignored.

#synthesize ivarName = _ivarName convention, preference or performance? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Synthesized property and variable with underscore prefix: what does this mean?
The usage of Objective-C properties has always felt awkward to me. It's one of the "I know how to use them, but I'm not always sure why I'm using them." kind of things and recently I've been seeing a lot of this:
// in .h file
#interface MyObject : NSObject
{
id _coolIvar;
}
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;// <- whats the point of that.
#end
So what is the point of declaring an ivar with an underscore and then using #synthesize to access it, Opposed to just declaring the #property with the same name as the ivar?
Side Question:
I've noticed that this convention has been becoming increasingly more popular since blocks started becoming the preferred approach for async callbacks opposed to the target/selector approach. Is that a coincidence or does the above #property declaration convention play nicer with block scopes?
It's preference.
It's also my preference to not declare the variables twice and just let them be synthesized like:
// in .h file
#interface MyObject : NSObject
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;
#end
The two reasons I like to use the _ prefix is
I know when I am going through an accessor and when I am accessing the variable straight.
If it makes sense for me to call an ivar address it is more than likely that inside a method a similar variable would also be logically called address. If my ivar does not have an _ prefix then my local address will mask the ivar address.
I also like how xcode will autocomplete vaiables starting with an _ when you start typing your #synthesize myVar = _...
NB
You may run into the odd name clash (I have only once) but the warning that the complier gives you makes it a pretty easy spot and simply changing the name is a quick win.
#isaac touched on not declaring ivars so that they are not publicly advertised but does not explain how/why. Basically you can declare #property's in a class extension to still give you the benefits of the #synthesized getter/setter but without making your public API look ugly.
Your previous example would look like this (if you wanted coolIvar to not be publicaly advertised):
// in .h file
#interface MyObject : NSObject
#end
// in .m file
#interface MyObject () <-- Like a category but with no name
#property (assign) id coolIvar;
#end
#implementation
#synthesize coolIvar = _coolIvar;
#end
I use the _ivar construct to make sure that I don't access the ivar directly (by mistake) when I really intend to go through the accessors.
With the modern runtime (iPhone applications and 64-bit programs on Mac OS X v10.5 and later) the ivar declaration is no longer required. So your code is reduced to:
// in .h file
#interface MyObject : NSObject
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;
#end
Per #Monolo's answer, the _ivar is a good failsafe to make sure you don't inadvertently access the ivar directly. Remember, the #property and #synthesize is there to replace boilerplate code - without it you'd have to code getter and setter accessors.
There are a couple benefits to differentiating ivars from property accessors.
One is described by Monolo - it prevents mistakingly accessing an ivar when what you intended to access was a property.
Another is that in theory it guards against collisions - cases where you might name an ivar identically to another ivar that's beyond your implementation (ie, a superclass ivar name).
There are different thoughts on best practices, but lately I've read in several places I consider reliable that the best practice is actually to no longer to declare ivars at all in your interfaces (ivars are created implicitly via the property declaration).
Some people don't like "implicit" - but there are material benefits: Not declaring them avoids advertising ivars that aren't really public. It also goes even further in avoiding collisions - because in theory when a property is synthesized and the ivar generated, it will do so without introducing a convention that may itself collide with a private ivar naming convention (as may be the case with preceding or trailing underscore).
Preference. Some people like to prefix instance variables with a underscore (so one can easily tell if one is referencing a ivar, or a variable in a more local scope), and some don't.

Since when is it possible to declare Objective-C 2.0 properties in a category?

I always thought that one cannot declare an object property in a category.
Until my partner did it in our app's code, and it seemed to work.
I went on a SO and Google binge to try to explain to him that no, Objective-C categories can only be used to add methods, not properties. I found questions such as:
Setting New Property In Category Interface Implementation (look at the accepted answer)
Can I add a property for a method not in my category?
But then I found this link on Apple's site that contains the following about the #property declaration:
A property declaration begins with the
keyword #property. #property can
appear anywhere in the method
declaration list found in the
#interface of a class. #property can
also appear in the declaration of a
protocol or category. (emphasis added)
I know that this doesn't work:
#interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
#end
But this compiles:
#interface MyClass ()
#property NSInteger foobar;
- (void) someCategorizedMethod;
#end
My question is (a) what's the best practice here? and (b) is this something that is new to Objective-C 2.0, and instead of using a "real" iVar, it simply uses associative storage behind the scenes to make this work?
You have always been able to declare an #property in a category. What you couldn't do -- and still can't -- is declare storage for the property in the category, neither as an instance variable nor via `#synthesize.
However....
#interface MyClass () is not a category. It is a class extension and has a distinctly more specific role than a category.
Namely, a class extension can be used to extend a class's #interface, and this includes #properties that can be #synthesized (including synthesizing storage in the modern runtime).
Foo.h:
#interface Foo
#end
Foo.m:
#interface Foo()
#property int x;
#end
#implementation Foo
#synthesize x; // synthesizes methods & storage
#end
it simply uses associative storage
behind the scenes to make this work?
Nope -- it is a real instance variable. The modern runtime fixes the fragile base class problem.
#interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
#end
The above doesn't work (as expected) because foobar is, effectively, a global variable.
If you change it to:
#interface MyClass () {
NSInteger foobar;
}
- (void) someCategorizedMethod;
#end
Then it'll work with the latest release of the llvm compiler (with the right flags, as #Joshua indicated in a comment).
Generally speaking, properties are nothing different from other methods. As long as the ivar used is available in the ordinary class, there is no problem at all. It's just syntactic sugar.
Things start to get more difficult if also the ivar is automatically created, as is possible in some configurations.
The main point here is that declaration of the ivar is independent from the property.
Assotiative storage is the solution.
Have a look at this post.

Setting Properties Rundown in Objective-C

One of the things I've been struggling with, whilst breaking into Objective-C programming, is understanding how to manipulate properties. I'm perhaps out of my comfort zone using a proper coding language as opposed to scripting languages that I'm used to, so the declaring things in header files and implementation files is confusing me somewhat.
Let's say I have a String. I wish to add some text into that string. What do I declare in the header file and what do I do in the implementation file to allow this to work properly, and what are #property and #synthesize?
In the bad old days before Objective-C 2.0, it was common to write getters and setters for your instance variables e.g.
#interface Foo : NSObject
{
#private
id foo;
}
-(void) setFoo: (id) newFoo;
-(id) foo;
#end
#implementation Foo
// need dealloc to release foo too.
-(void) setFoo: (id) newFoo
{
[newFoo retain];
[foo release];
foo = newFoo;
}
-(id) foo
{
return foo;
}
#end
And that's just in the single threaded environment. There was even more stuff needed for multithreaded apps.
Properties provide a neat shorthand for the above. The #property replaces both of the declarations in the interface as well as giving the caller better hints about the semantics of the getter and setter. It also allows you to #synthesize the accessors so the compiler will generate the code for them automatically (you don't have to #synthesize them, you can provide your own implementations if you want). All of the above can be replaced by
#interface Foo : NSObject
{
#private
id foo;
}
#property (nonatomic, retain) id foo;
#end
#implementation Foo
// need dealloc to release foo too.
#synthesize foo;
#end
That saves quite a lot of typing but also you can see from the interface that setFoo: will retain its new value and that the property is not safe to use (to set or get) in a multithreaded environment (without some other locking mechanism).
#property - declares a property with access and memory modifiers. Properties can be readonly or readwrite, nonatomic or atomic (thread safety), assign/retain/copy managed. Actually, you can declare simple getter and setter methods like we did in the Tiger era, but declaring a #property will help you to identify all aspects of the property at any time without checking the implementation.
#synthesize - simplifies the job if you need a simple property without any complex job in getter and setter. It defines a default implementation according to the definition of #property.
At last, your questions about string. Properties won't help here if you are looking for something simple, let's say myObj.string += "abc". It's not Objective-C style and with or without property you will do something like myObj.string = [[myObj string] stringByAppendingString:#"abc"] or [[myObj string] appendString:#"abc"] depending on mutable/immutable nature of the string object.
As a bottom line: it's quite a big topic to explain everything in a single post. I'd recommend you to read Apple documentation and maybe purchase a book about Objective-C. Aaron Hillegass wrote one - a good start for any Objective-C and Mac OS X beginner.

Do declared properties require a corresponding instance variable?

Do properties in Objective-C 2.0 require a corresponding instance variable to be declared? For example, I'm used to doing something like this:
MyObject.h
#interface MyObject : NSObject {
NSString *name;
}
#property (nonatomic, retain) NSString *name;
#end
MyObject.m
#implementation
#synthesize name;
#end
However, what if I did this instead:
MyObject.h
#interface MyObject : NSObject {
}
#property (nonatomic, retain) NSString *name;
#end
Is this still valid? And is it in any way different to my previous example?
If you are using the Modern Objective-C Runtime (that's either iOS 3.x or greater, or 64-bit Snow Leopard or greater) then you do not need to define ivars for your properties in cases like this.
When you #synthesize the property, the ivar will in effect be synthesized also for you. This gets around the "fragile-ivar" scenario. You can read more about it on Cocoa with Love
In your interface, you can formally declare an instance variable between the braces, or via #property outside the braces, or both. Either way, they become attributes of the class. The difference is that if you declare #property, then you can implement using #synthesize, which auto-codes your getter/setter for you. The auto-coder setter initializes integers and floats to zero, for example. IF you declare an instance variable, and DO NOT specify a corresponding #property, then you cannot use #synthesize and must write your own getter/setter.
You can always override the auto-coded getter/setter by specifying your own. This is commonly done with the managedObjectContext property which is lazily loaded. Thus, you declare your managedObjectContext as a property, but then also write a -(NSManagedObjectContext *)managedObjectContext method. Recall that a method, which has the same name as an instance variable/property is the "getter" method.
The #property declaration method also allows you other options, such as retain and readonly, which the instance variable declaration method does not. Basically, ivar is the old way, and #property extends it and makes it fancier/easier. You can refer to either using the self. prefix, or not, it doesn't matter as long as the name is unique to that class. Otherwise, if your superclass has the same name of a property as you, then you have to say either like self.name or super.name in order to specify which name you are talking about.
Thus, you will see fewer and fewer people declare ivars between the braces, and instead shift toward just specifying #property, and then doing #synthesize. You cannot do #synthesize in your implementation without a corresponding #property. The Synthesizer only knows what type of attribute it is from the #property specification. The synthesize statement also allows you to rename properties, so that you can refer to a property by one name (shorthand) inside your code, but outside in the .h file use the full name. However, with the really cool autocomplete that XCode now has, this is less of an advantage, but is still there.
Hope this helps clear up all the confusion and misinformation that is floating around out there.
it works both ways but if you don't declare them in the curly braces, you won't see their values in the debugger in xcode.
From the documentation:
In general the behavior of properties is identical on both modern and legacy runtimes (see “Runtime Versions and Platforms” in Objective-C Runtime Programming Guide). There is one key difference: the modern runtime supports instance variable synthesis whereas the legacy runtime does not.
For #synthesize to work in 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. With the modern runtime, if you do not provide an instance variable, the compiler adds one for you.
If you are using XCode 4.4 or later it will generate instance variable synthesizing code for you.
You just have to declare properties like below; it will generate synthesizing code and instance variable declaring code for you.
#property (nonatomic, strong) NSString *name;
it will generate synthesizing code as
#synthesize name = _name;
and you can access instance variable using _name
it is similar to declare
NSString* _name
but if you declare read-only property it like
#property (nonatomic, strong, readonly) NSString *name;
it will generate code
#synthesize name;
or
#synthesize name = name;
So you should access instant variable name with out prefix "_"
any way you can write your own synthesizing code then compiler will generate code for you.
you can write
#synthesize name = _name;
The Objective-C Programming Language: Property Implementation Directives
There are differences in the behavior of accessor synthesis that depend on the runtime (see also “Runtime Difference”):
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 (see “Runtime Versions and Platforms” in Objective-C Runtime Programming Guide), instance variables are synthesized as needed. If an instance variable of the same name already exists, it is used.