Do "atomic" and "nonatomic" attributes on properties have any effect if you use a custom getter/setter? - objective-c

If I have a property declared in a class:
#interface MyClass : NSObject
#property (atomic) NSString *myString;
#end
And I implement custom getter and setter methods:
#implementation MyClass
- (NSString *)myString
{
// return something
}
- (void)setMyString
{
// do something
}
#end
Does the "atomic" attribute on the property declaration actually do anything? Or is it only used if an automatic getter/setter is actually created by the compiler?
Assuming the "atomic" and "nonatomic" keywords don't do anything for properties with custom getters and setters, is there any convention for what attribute we should use for those properties?

Does the atomic attribute on the property declaration actually do anything? Or is it only used if an automatic getter/setter is actually created by the compiler?
atomic is used only when a getter/setter is synthesized by the compiler. It is also used to check the consistency of accessors for readwrite properties:
Because the internal implementation and synchronization of atomic accessor methods is private, it’s not possible to combine a synthesized accessor with an accessor method that you implement yourself. You’ll get a compiler warning if you try, for example, to provide a custom setter for an atomic, readwrite property but leave the compiler to synthesize the getter.
is there any convention for what attribute we should use for those properties?
Apple does not require you to follow any convention, but you could use atomic and nonatomic attributes to document your own code. This would let readers of your code learn about the behavior of your accessors without looking into their implementation.

Related

When should I use #synthesize explicitly?

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!

Properties and accessor methods without member in objective-c

I was just going through properties documentation in the link: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
The section' You Can Implement Custom Accessor Methods' describes that Properties don’t always have to be backed by their own instance variables. The example of fullName also does not use its own corresponding member.
Won't the compiler implicitly create a member when a property is defined (_propertyName)?
If you create a property using #property, then an ivar is created automatically and its setter and getters are created by LLVM compiler.
Whereas when you create an ivar, you have to create a setter/getter for it. Typically you do with #property and leave rest on the compiler.
However in some cases you create ivar and property with different name and put a reference to it as :
#synthesize boxDescription=boxName;
Now boxName is accessor for boxDescription, now you cant use boxDescription in your code.
if you override the default setter and getter, and you dont provide the #synthesize (and as well you dont access the _ivar), no variable is created for you by the compiler. in that case you have a property that is not backed by an ivar.
as a very random example:
#property (nonatomic) int x;
- (int)x
{
return 1;
}
- (void)setX:(int)x
{
NSLog(#"%d", x);
}
a more userfull usage can be if you have a facade for other classes, and you use this setter/getter to set/get those.
in case you don't override the set/getter and now that #synthesize is not mandatory anymore by default the compiler creates an ivar named _propertyname, you can override this behavious by #synthesize prop_name=ivar_name

Should I use strong properties for properties with custom getters and setters?

I store some data in NSUserDefaults and keychain and I have a wrapper. For example
- (NSString *)userPassword
{
return [UICKeyChainStore stringForKey:KEY_USER_PASSWORD];
}
- (void)setUserPassword:(NSString *)userPassword
{
[UICKeyChainStore setString:userPassword forKey:KEY_USER_PASSWORD];
}
How should properties definition look like? Now I use as follows
#property (nonatomic, strong) NSString *userEmail;
But now I have a doubt if I should use strong statement there since I haven't an ivar for it.
Thanks in advance.
strong or weak both will be fine.
Its your custom method, this implies that you are overriding the compiler's method, or rather compiler will not create methods for those properties.
EDIT:
One more thing for you :)
Is there any advantage of having atomic property for saving in keychains/userdefaults?
You can use strong properties.
Here you are implementing your own setter and getter which means you are only overriding the methods of compiler so If you want to use you can else it is also fine.

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.

Property vs. ivar in times of ARC

It is my understanding that setting an ivar now retains the object being assigned to it, since setting variables defaults to the strong qualifier. Because ivars are in the scope of the object they are declared in and strong retains objects within the scope of the variable, this means the ivars value would never be released while the object containing the ivar is still alive.
Is this correct?
If so, am I right in thinking that there is, in terms of memory management, no difference between a retaining (strong) property and a simple ivar anymore?
If a variable:
Is declared in a class using ARC.
Is used solely for class implementation (not exposed as part of the class interface).
Does not require any KVO.
Does not require any custom getter/setter.
Then it is appropriate to declare it as an ivar without a corresponding #property/#synthesize, and to refer to it directly within the implementation. It is inline with Encapsulation to declare this ivar in the class implementation file.
// MyClass.h
#interface MyClass : ParentClass
#end
// MyClass.m
#implementation MyClass {
NSString *myString;
}
- (void)myMethod {
myString = #"I'm setting my ivar directly";
}
#end
This ivar will be treated as __strong by the ARC compiler.
It will be initialized to nil if it is an object, or 0 if it is a primitive.
You can't use KVO and do custom getter and setters with instance variables other than that they are very similar when using ARC.