When should I use #synthesize explicitly? - objective-c

As far as I know, since XCode 4.4 the #synthesize will auto-generate the property accessors. But just now I have read a sample of code about NSUndoManager, and in the code it noticed that the #synthesize is added explicitly. Like:
#interface RootViewController ()
#property (nonatomic, strong) NSDateFormatter *dateFormatter;
#property (nonatomic, strong) NSUndoManager *undoManager;
#end
#implementation RootViewController
//Must explicitly synthesize this
#synthesize undoManager;
I am feeling puzzled now... When should I add #synthesize explicitly to my code?

There's a lot of answers, but also a big confusion. I'll try to put some order (or increase the mess, we'll see...)
Let's stop talking about Xcode. Xcode is an IDE. clang is a compiler. This feature we are discussing is called autosynthesis of properties and it's an Objective-C language extension supported by clang, which is the default compiler used by Xcode.
Just to make it clear, if you switch to gcc in Xcode, you won't benefit from this feature (regardless from the Xcode version.) In the same way if you use a text editor and compile using clang from the command line, you will.
Thank to autosynthesis you don't need to explicitly synthesize the property as it will be automatically synthesized by the compiler as
#synthesize propertyName = _propertyName
However, a few exceptions exist:
readwrite property with custom getter and setter
when providing both a getter and setter custom implementation, the property won't be automatically synthesized
readonly property with custom getter
when providing a custom getter implementation for a readonly property, this won't be automatically synthesized
#dynamic
when using #dynamic propertyName, the property won't be automatically synthesized (pretty obvious, since #dynamic and #synthesize are mutually exclusive)
properties declared in a #protocol
when conforming to a protocol, any property the protocol defines won't be automatically synthesized
properties declared in a category
this is a case in which the #synthesize directive is not automatically inserted by the compiler, but this properties cannot be manually synthesized either. While categories can declare properties, they cannot be synthesized at all, since categories cannot create ivars. For the sake of completeness, I'll add that's it's still possible to fake the property synthesis using the Objective-C runtime.
overridden properties (new since clang-600.0.51, shipping with Xcode 6, thanks Marc Schlüpmann)
when you override a property of a superclass, you must explicitly synthesize it
It's worth noting that synthesizing a property automatically synthesize the backing ivar, so if the property synthesis is missing, the ivar will be missing too, unless explicitly declared.
Except for the last three cases, the general philosophy is that whenever you manually specify all the information about a property (by implementing all the accessor methods or using #dynamic) the compiler will assume you want full control over the property and it will disable the autosynthesis on it.
Apart from the cases that are listed above, the only other use of an explicit #synthesize would be to specify a different ivar name. However conventions are important, so my advice is to always use the default naming.

If you do not explicitly use #synthesize the compiler will understand your property the same way if you had written
#synthesize undoManager=_undoManager;
then you will be able to write in your code things like :
[_undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter
This is the common convention.
if you write
#synthesize undoManager;
you will have :
[undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter
Personally I stop using #synthesize, since it's not mandatory any more.
For me the only reason to use #synthesize is to link an iVar to a #property. If you want to generate specific getter and setter for it.
But in the given piece of code there is no iVar, I think that this #synthesize is useless. But now I think the new question is "When to use iVar ?", and I've no other response than "never" for this one !

When should I add #synthesize explicitly to my code?
Generally, if it's required: You will probably never hit a case where it's needed.
There's one case you might find it useful, though.
Say you're writing both a custom getter and setter, but want an instance variable to back it. (For an atomic property, this is as simple as wanting a custom setter: the compiler will write a getter if you specify a setter for a monatomic property, but not an atomic property.)
Consider this:
#interface MyObject:NSObject
#property (copy) NSString *title;
#end
#implementation MyObject
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
#end
This will not work, because _title doesn't exist. You've specified both a getter or setter, so Xcode (correctly) doesn't create a backing instance variable for it.
You have two choices for making it exist. You can either change the #implementation to this:
#implementation MyObject {
NSString *_title;
}
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
#end
Or change it to this:
#implementation MyObject
#synthesize title = _title;
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
#end
In other words, although synthesize is for practical purposes never necessary*, it can be used to define property-backing instance variables when you're providing a getter/setter. You can decide which form here you want to use.
In the past, I've favoured specifying the instance variable in the #implementation {}, but I now think the #synthesize route is a better choice as it removes the redundant type and explicitly ties the backing variable to the property:
Change the property's type, and the instance variable's type changes.
Change its storage qualifier (for instance, make it weak instead of strong or strong instead of weak) and the storage qualifier changes.
Remove or rename the property, and the #synthesize will generate a compiler error. You won't end up with stray instance variables.
*-I know one case where it was necessary, relating to splitting functionality across categories in multiple files. And I wouldn't be surprised if Apple fixes this, or even already has.

OK, when you create a property...
#property NSString *name;
Xcode will auto synthesise an iVar as if you had written...
#synthesize name = _name;
This means you can access the property with...
self.name;
// or
_name;
Either will work but only self.name actually uses the accessor methods.
There is only one time that auto synthesise does not work: If you overwrite but the setter AND the getter method then you will need to synthesise the iVar.
You are fine if you just override the setter or if you just override the getter. But if you do both then the compiler won't understand it and you will need to synthesise it manually.
As a rule of thumb though.
Don't make iVars.
Just use the property.
Don't synthesise it.

Property synthesis is required when a property is declared in a protocol. It will not be automatically synthesized in an implementing interface.

Thanks for clarifying that. I had a similar problem.
#synthesize firstAsset, secondAsset, audioAsset;
#synthesize activityView;
So now, having commented them out, I went through and replaced each occurrence with, for example
self.firstAsset It seems I could also use firstAsset, but I find I miss seeing the "" too often.

Xcode doesn't require an explicit #synthesize declaration.
If you don't write #synthesize its the same as doing :
#synthesize manager = _manager;
The sample code might've been old. They'll update it soon.
You can access your properties like :
[self.manager function];
This is Apple's recommended convention. I follow it, and I recommend that you do too!

Related

use of #property and #synthesise?

I was wondering what the point of #property and #synthesise were. At the moment I use the following to declare something:
//Class.m
#import "Class.h"
CCNode *node;
#implementation
//init, etc..
But I have seen others use:
#property (nonatomic, etc..) CCNode* node;
#synthesise (nonatomic, etc..) node;
//I am not too sure on how this type of declaration works, please correct me on how it's done.
They both seem to work in the same way, what are the advantages of the #property and #synthesise way? Do they do different things, if so, what?
#property and #synthesize are two objective C keyword that allow you to easily create your properties and therefore avoid to write by hand getters and setters methods of the property.
The #property define the property itself, should be placed in the header file and can get some attributes (as for example : strong, nonatomic, retain assign, copy), the #synthesize should be placed into the implementation file and tell the compiler to generate the body of getter and setter method.
These two keyword are extremely useful when coupled with the right use of their attributes, because they take care of the generation of the property code and most of all they take care of the memory management of the property.
#property - create the declaration of your getter and setter.
#synthesize - provide the definition of getter and setter based upon the parameters which are passed inside property.
Check this out, there are a lot more details about the same present there - https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html
on using #property the compiler will take care of declaring getter and setter methods based on readonly and readwrite
readonly -> getterMethod
readwrite -> both setter and getter method
on using #synthesize the compiler will take care of defining getter and setter methods
If you have an instance variable (ivar) in your class, you can't access it from other classes usually. So you have to make public accessor methods (getters and setters). They look something like this:
Setter:
- (void)setMyVariable:(SomeClass *)newValue {
if (newValue != myVariable) {
[myVariable release];
myVariable = [newValue retain];
}
}
Getter:
- (SomeClass *)myVariable {
return myVariable;
}
This was the way you had to do it before Objective-C 2.0. Now you can use #property and #synthesize to speed this up. It's basically just a shortcut.
In the header you use #property to define what kind of setters you want. Should the setter retain the passed value (like in my example) or copy or just assign?
And in the implementation you just write #synthesize to make the compiler include the automatically created getters and setters at that position. Usually at the top of your implementation.
My feeling is that all iVars should have an associated underscore synthesised property (using an _iVar prevents accidental direct access), and all access to the iVars, apart from init and dealloc methods, should via the property.
IMHO the big win is memory management - it's safer and much easier as there is no need to remember which iVars have been retained.
And think of how much work is required to code an accessor - 4 lines for getter and 2 for a setter.
At some point in the future #synthesize is likely to be optional, so all you'll need is the #property.

Differentiate between iVar and Method Parameter?

I have a property like this:
#property (nonatomic, strong) IBOutlet UIImageView *backgroundImageHolder;
I want to adjust the setter, and XCode fills out the method signature like this:
-(void)setBackgroundImageHolder:(UIImageView *)backgroundImageHolder {
However, to actually do anything in the method, I must change the parameter backgroundImageHolder to something like backgroundImageHolderIn. Is there any way to avoid this? Is there any way to set the iVar without reinvoking the setter (causing an endless loop), or just referring to the parameter again?
I just tried:
self->backgroundImageHolder = backgroundImageHolder;
but the compiler warns me anyway.
Note: I am using the automagically generated iVar that the compiler makes for the property, but by default its name is the same.
You can give tell the compiler how to name the generated ivar:
#synthesize propertyName = iVarName;
If there actually exists an ivar named iVarName that one is used. If it doesn't exist the compiler creates it for you.
Like:
#synthesize backgroundImageHolder = myBackgroundImageHolder;
Now you can access the instance variable myBackgroundImageHolder. You don't need to declare it in the interface first.
Well, the conflicting parameter name seems to be pretty well covered by now. Basically, you have to either:
Rename the incoming argument
Rename the synthesized iVar
Once you have a method argument that differs from the iVar you're attempting to set, you have everything you need to write a custom setter. To avoid the infinite loop, you have to not call the setter you're currently implementing, whether it be via dot syntax or method brace syntax. Instead, refer directly to the backing iVar. You'll need to take care to manually implement the memory management semantics you declared in the property though (assign vs. retain, etc.):
// Backed by _myProperty iVar.
- (void)setMyProperty:(NSInteger)myProperty {
// Insert custom code here...
[self setMyProperty:myProperty]; // Obviously bad.
self.myProperty = myProperty; // Less obviously bad (thanks dot syntax)
// but semantically identical to the previous line.
_myProperty = myProperty // Good, (assuming assign semantics).
}
Compiler warns you because when you declare #property it creates instance variable with exact same name as a property (and as a parameter of a setter method). One way to avoid it is to create differently named instance variable and then pair it with property using #synthesize like this:
// .h
#interface Foo : NSObject {
IBOutlet UIImageView *myfooImageView;
}
#property (nonatomic, retain) UIImageView *publicFooImageView;
// .m
#implementation Foo
#synthesize publicFooImageView=myfooImageView;
#end
The clearest thing to do would be this:
In your header, define an iVar for backgroundImageHolder like so
#interface Something : NSObject
{
IBOutlet UIImageView *_backgroundImageHolder
}
Notice the leading underscore.
Then in your .m file, use either the synthesize call like so:
#synthesize backgroundImageHolder=_backgroundImageHolder;
or just define the getter and setter methods yourself: Then you are able to access the ivar via "_backgroundImageHolder" without any danger of accidentally calling the setter again.

Why alias a new name and explicitly release the IBOutlet property?

Recently some example from Apple looks something like this:
#interface ViewController : UIViewController
{
**// Notice no more ivar here.**
}
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
#implementation ViewController
#synthesize webView = _webView;
...
- (void)dealloc
{
[_webView release];
[super dealloc];
}
My question is why aliasing the webView to _webView, and release in the dealloc since there is no ivar named _webView?
One more question, if I declare a property that has no related ivar, do I need to release it in dealloc?
When you #synthesize a property that doesn't have an associated ivar (whether you say #synthesize property or #synthesize property=_property), an ivar is generated for you. The default is to use the same name for the ivar as the property itself. If the property is a retain property, then you have to release the object in -dealloc or you'll have a memory leak.
Apple's convention is to name ivars (whether declared explicitly in the interface or implicitly in an #synthesize) with an underbar to indicate the private nature of the ivar. IMO it's also helpful to ensure that people use the ivar only when they intend to (since for some coders it seems to be easy to accidentally type myproperty when you mean self.myproperty, which can create significant bugs).
The answer to your last question is basically yes, though technically the answer is 'sometimes'. You only have to release the object if there is an object stored in an ivar that was retained. That's most of the time. However, properties are just a shortcut for invoking methods named 'myproperty' and 'setMyproperty' (etc), so it's possible to have a pair of methods with those names and an associated property that doesn't actually have an ivar paired with it. But if you're declaring properties with the retain attribute and synthesizing them, you should always release the objects their ivars point to.
I think Use of properties by Xcode 4 templates will explain this better and more in detail than I could.

Objective-C setter/getter naming conventions drive me mad?

I have been trying to understand something for several hours and I would like to get your point of view.
I have setter/getter on one of my class properties (I noticed that I MUST add "set" in front of the setter name else the compiler says that there is no setter):
#property (nonatomic, retain, readwrite, setter=setTopString:, getter=TopString) NSString* m_topString;
When I call the setter like this, the compiler is happy:
[secureKeyboardController setTopString:#"This action requires that your enter your authentication code."];
But when I try to use the "dot" convention, then I am rejected by the compiler:
secureKeyboardController.topString = #"This action requires that your enter your authentication code.";
What is really weird is that the dot naming convention works fine with this property:
#property (nonatomic, readwrite, getter=PINMaxLength, setter=setPINMaxLength:) NSInteger m_PINMaxLength;
In this case i can do:
[secureKeyboardController setPINMaxLength:10];enter code here
or
secureKeyboardController.PINMaxLength = 10;
In both cases, the compiler is happy.
I really would like to fall asleep tonigh less stupid than I currently feel now. Thus any explanation would be greatly appreciated.
Regards,
Apple92
What you're doing is declaring properties as if you were declaring instance variables. You should not be using the names in the getter and setter attributes on the #property declaration with dot syntax; that it happens to be working now is not - so far as I know - by design.
The property should be what you use with dot syntax. For some reason - unfamiliarity with Cocoa coding conventions, I expect - you named your properties m_topString and m_PINMaxLength. That means you should use them as someObject.m_topString and someObject.m_PINMaxLength.
If you want to use those names for the instance variables that you've decided to use for the properties' backing storage, you should declare that in the #synthesize directive instead.
This is how your class should look, to be more in line with regular Cocoa and Objective-C coding conventions:
#interface SomeClass : NSObject {
#private
NSString *m_topString;
}
#property (nonatomic, readwrite, copy) NSString *topString;
- (id)initWithTopString:(NSString *)initialTopString;
#end
#implementation SomeClass
#synthesize topString = m_topString;
// this says to use the instance variable m_topString
// for the property topString's storage
- (id)initWithTopString:(NSString *)initialTopString {
if ((self = [super init])) {
m_topString = [initialTopString copy];
// use the ivar directly in -init, not the property
}
return self;
}
- (void)dealloc {
[m_topString release];
// use the ivar directly in -dealloc, not the property
[super dealloc];
}
- (NSString *)description {
return [NSString stringWithFormat:#"SomeClass (%#)", self.topString];
// elsewhere in your class, use the property
// this will call through its getter and setter methods
}
#end
You are trying to fight the compiler, and the compiler fights back.
You are trying to declare a property named m_topString with setter setTopString and getter TopString, and that is plainly stupid. You are writing Objective-C code, not C++. Your code will be a maintenance nightmare (unless the next maintainer is just sensible and changes your code to Objective-C conventions).
Do yourself a favour, start writing Objective-C code. Just call the property topString, don't pick your own names for the setter and getter, don't pick your own names for the instance variable, and everything works just fine.
Capitalize the T in TopString, i.e. secureKeyboardController.TopString
I'm 90% sure that will fix your problem.

What is the difference between ivars and properties in Objective-C

What is the semantic difference between these 3 ways of using ivars and properties in Objective-C?
1.
#class MyOtherObject;
#interface MyObject {
}
#property (nonatomic, retain) MyOtherObject *otherObj;
2.
#import "MyOtherObject.h"
#interface MyObject {
MyOtherObject *otherObj;
}
#property (nonatomic, retain) MyOtherObject *otherObj;
3.
#import "MyOtherObject.h"
#interface MyObject {
MyOtherObject *otherObj;
}
Number 1 differs from the other two by forward declaring the MyOtherObject class to minimize the amount of code seen by the compiler and linker and also potentially avoid circular references. If you do it this way remember to put the #import into the .m file.
By declaring an #property, (and matching #synthesize in the .m) file, you auto-generate accessor methods with the memory semantics handled how you specify. The rule of thumb for most objects is Retain, but NSStrings, for instance should use Copy. Whereas Singletons and Delegates should usually use Assign. Hand-writing accessors is tedious and error-prone so this saves a lot of typing and dumb bugs.
Also, declaring a synthesized property lets you call an accessor method using dot notation like this:
self.otherObj = someOtherNewObject; // set it
MyOtherObject *thingee = self.otherObj; // get it
Instead of the normal, message-passing way:
[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it
Behind the scenes you're really calling a method that looks like this:
- (void) setOtherObj:(MyOtherObject *)anOtherObject {
if (otherObject == anOtherObject) {
return;
}
MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
otherObject = [anOtherObject retain]; // put the new value in
[oldOtherObject release]; // let go of the old object
} // set it
…or this
- (MyOtherObject *) otherObject {
return otherObject;
} // get it
Total pain in the butt, right. Now do that for every ivar in the class. If you don't do it exactly right, you get a memory leak. Best to just let the compiler do the work.
I see that Number 1 doesn't have an ivar. Assuming that's not a typo, it's fine because the #property / #synthesize directives will declare an ivar for you as well, behind the scenes. I believe this is new for Mac OS X - Snow Leopard and iOS4.
Number 3 does not have those accessors generated so you have to write them yourself. If you want your accessor methods to have side effects, you do your standard memory management dance, as shown above, then do whatever side work you need to, inside the accessor method. If you synthesize a property as well as write your own, then your version has priority.
Did I cover everything?
Back in the old days you had ivars, and if you wanted to let some other class set or read them then you had to define a getter (i.e., -(NSString *)foo) and a setter (i.e., -(void)setFoo:(NSString *)aFoo;).
What properties give you is the setter and getter for free (almost!) along with an ivar. So when you define a property now, you can set the atomicity (do you want to allow multiple setting actions from multiple threads, for instance), as well as assign/retain/copy semantics (that is, should the setter copy the new value or just save the current value - important if another class is trying to set your string property with a mutable string which might get changed later).
This is what #synthesize does. Many people leave the ivar name the same, but you can change it when you write your synthesize statement (i.e., #synthesize foo=_foo; means make an ivar named _foo for the property foo, so if you want to read or write this property and you do not use self.foo, you will have to use _foo = ... - it just helps you catch direct references to the ivar if you wanted to only go through the setter and getter).
As of Xcode 4.6, you do not need to use the #synthesize statement - the compiler will do it automatically and by default will prepend the ivar's name with _.