#property retain, assign, copy, nonatomic in Objective-C - ios

As someone that's new to Objective-C can someone give me an overview of the retain, assign, copy and any others I'm missing, that follow the #property directive? What are they doing and why would I want to use one over another?

Before you know about the attributes of #property, you should know what is the use of #property.
#property offers a way to define the information that a class is intended to encapsulate.
If you declare an object/variable using #property, then that object/variable will be accessible to other classes importing its class.
If you declare an object using #property in the header file, then you have to synthesize it using #synthesize in the implementation file. This makes the object KVC compliant. By default, compiler will synthesize accessor methods for this object.
accessor methods are : setter and getter.
Example:
.h
#interface XYZClass : NSObject
#property (nonatomic, retain) NSString *name;
#end
.m
#implementation XYZClass
#synthesize name;
#end
Now the compiler will synthesize accessor methods for name.
XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:#"liza"]; // first letter of 'name' becomes capital in setter method
List of attributes of #property
atomic, nonatomic, retain, copy, readonly, readwrite, assign, strong, getter=method, setter=method, unsafe_unretained
atomic is the default behavior. If an object is declared as atomic then it becomes thread-safe. Thread-safe means, at a time only one thread of a particular instance of that class can have the control over that object.
If the thread is performing getter method then other thread cannot perform setter method on that object. It is slow.
#property NSString *name; //by default atomic`
#property (atomic)NSString *name; // explicitly declared atomic`
nonatomic is not thread-safe. You can use the nonatomic property attribute to specify that synthesized accessors simply set or return a value directly, with no guarantees about what happens if that same value is accessed simultaneously from different threads.
For this reason, it’s faster to access a nonatomic property than an atomic one.
#property (nonatomic)NSString *name;
retain is required when the attribute is a pointer to an object.
The setter method will increase retain count of the object, so that it will occupy memory in autorelease pool.
#property (retain)NSString *name;
copy If you use copy, you can't use retain. Using copy instance of the class will contain its own copy.
Even if a mutable string is set and subsequently changed, the instance captures whatever value it has at the time it is set. No setter and getter methods will be synthesized.
#property (copy) NSString *name;
now,
NSMutableString *nameString = [NSMutableString stringWithString:#"Liza"];
xyzObj.name = nameString;
[nameString appendString:#"Pizza"];
name will remain unaffected.
readonly If you don't want to allow the property to be changed via setter method, you can declare the property readonly.
Compiler will generate a getter, but not a setter.
#property (readonly) NSString *name;
readwrite is the default behavior. You don't need to specify readwrite attribute explicitly.
It is opposite of readonly.
#property (readwrite) NSString *name;
assign will generate a setter which assigns the value to the instance variable directly, rather than copying or retaining it. This is best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates.
Keep in mind retain and assign are basically interchangeable when garbage collection is enabled.
#property (assign) NSInteger year;
strong is a replacement for retain.
It comes with ARC.
#property (nonatomic, strong) AVPlayer *player;
getter=method If you want to use a different name for a getter method, it’s possible to specify a custom name by adding attributes to the property.
In the case of Boolean properties (properties that have a YES or NO value), it’s customary for the getter method to start with the word “is”
#property (getter=isFinished) BOOL finished;
setter=method If you want to use a different name for a setter method, it’s possible to specify a custom name by adding attributes to the property.
The method should end with a colon.
#property(setter = boolBool:) BOOL finished;
unsafe_unretained There are a few classes in Cocoa and Cocoa Touch that don’t yet support weak references, which means you can’t declare a weak property or weak local variable to keep track of them. These classes include NSTextView, NSFont and NSColorSpace,etc. If you need to use a weak reference to one of these classes, you must use an unsafe reference.
An unsafe reference is similar to a weak reference in that it doesn’t keep its related object alive, but it won’t be set to nil if the destination object is deallocated.
#property (unsafe_unretained) NSObject *unsafeProperty;
If you need to specify multiple attributes, simply include them as a comma-separated list, like this:
#property (readonly, getter=isFinished) BOOL finished;

The article linked to by MrMage is no longer working. So, here is what I've learned in my (very) short time coding in Objective-C:
nonatomic vs. atomic
- "atomic" is the default. Always use "nonatomic". I don't know why, but the book I read said there is "rarely a reason" to use "atomic". (BTW: The book I read is the BNR "iOS Programming" book.)
readwrite vs. readonly
- "readwrite" is the default. When you #synthesize, both a getter and a setter will be created for you. If you use "readonly", no setter will be created. Use it for a value you don't want to ever change after the instantiation of the object.
retain vs. copy vs. assign
"assign" is the default. In the setter that is created by #synthesize, the value will simply be assigned to the attribute. My understanding is that "assign" should be used for non-pointer attributes.
"retain" is needed when the attribute is a pointer to an object. The setter generated by #synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it.
"copy" is needed when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.

After reading many articles I decided to put all the attributes information together:
atomic //default
nonatomic
strong=retain //default
weak= unsafe_unretained
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
Below is a link to the detailed article where you can find these attributes.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
Here is the Sample Description from Article
atomic
-Atomic means only one thread access the variable(static type).
-Atomic is thread safe.
-but it is slow in performance
-atomic is default behavior
-Atomic accessors in a non garbage collected environment (i.e. when using retain/release/autorelease) will use a lock to
ensure that another thread doesn't interfere with the correct setting/getting of the value.
-it is not actually a keyword.
Example :
#property (retain) NSString *name;
#synthesize name;
nonatomic
-Nonatomic means multiple thread access the variable(dynamic type).
-Nonatomic is thread unsafe.
-but it is fast in performance
-Nonatomic is NOT default behavior,we need to add nonatomic keyword in property attribute.
-it may result in unexpected behavior, when two different process (threads) access the same variable at the same time.
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
Explain:
Suppose there is an atomic string property called "name", and if you call [self setName:#"A"] from thread A,
call [self setName:#"B"] from thread B, and call [self name] from thread C, then all operation on different thread will be performed serially which means if one thread is executing setter or getter, then other threads will wait. This makes property "name" read/write safe but if another thread D calls [name release] simultaneously then this operation might produce a crash because there is no setter/getter call involved here. Which means an object is read/write safe (ATOMIC) but not thread safe as another threads can simultaneously send any type of messages to the object. Developer should ensure thread safety for such objects.
If the property "name" was nonatomic, then all threads in above example - A,B, C and D will execute simultaneously producing any unpredictable result. In case of atomic, Either one of A, B or C will execute first but D can still execute in parallel.
strong (iOS4 = retain )
-it says "keep this in the heap until I don't point to it anymore"
-in other words " I'am the owner, you cannot dealloc this before aim fine with that same as retain"
-You use strong only if you need to retain the object.
-By default all instance variables and local variables are strong pointers.
-We generally use strong for UIViewControllers (UI item's parents)
-strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.
Example:
#property (strong, nonatomic) ViewController *viewController;
#synthesize viewController;
weak (iOS4 = unsafe_unretained )
-it says "keep this as long as someone else points to it strongly"
-the same thing as assign, no retain or release
-A "weak" reference is a reference that you do not retain.
-We generally use weak for IBOutlets (UIViewController's Childs).This works because the child object only
needs to exist as long as the parent object does.
-a weak reference is a reference that does not protect the referenced object from collection by a garbage collector.
-Weak is essentially assign, a unretained property. Except the when the object is deallocated the weak pointer is automatically set to nil
Example :
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#synthesize myButton;
Strong & Weak Explanation, Thanks to BJ Homer:
Imagine our object is a dog, and that the dog wants to run away (be deallocated).
Strong pointers are like a leash on the dog. As long as you have the leash attached to the dog, the dog will not run away. If five people attach their leash to one dog, (five strong pointers to one object), then the dog will not run away until all five leashes are detached.
Weak pointers, on the other hand, are like little kids pointing at the dog and saying "Look! A dog!" As long as the dog is still on the leash, the little kids can still see the dog, and they'll still point to it. As soon as all the leashes are detached, though, the dog runs away no matter how many little kids are pointing to it.
As soon as the last strong pointer (leash) no longer points to an object, the object will be deallocated, and all weak pointers will be zeroed out.
When we use weak?
The only time you would want to use weak, is if you wanted to avoid retain cycles
(e.g. the parent retains the child and the child retains the parent so neither is ever released).
retain = strong
-it is retained, old value is released and it is assigned
-retain specifies the new value should be sent -retain on assignment and the old value sent -release
-retain is the same as strong.
-apple says if you write retain it will auto converted/work like strong only.
-methods like "alloc" include an implicit "retain"
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
assign
-assign is the default and simply performs a variable assignment
-assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
-I would use assign for C primitive properties and weak for weak references to Objective-C objects.
Example:
#property (nonatomic, assign) NSString *address;
#synthesize address;
unsafe_unretained
-unsafe_unretained is an ownership qualifier that tells ARC how to insert retain/release calls
-unsafe_unretained is the ARC version of assign.
Example:
#property (nonatomic, unsafe_unretained) NSString *nickName;
#synthesize nickName;
copy
-copy is required when the object is mutable.
-copy specifies the new value should be sent -copy on assignment and the old value sent -release.
-copy is like retain returns an object which you must explicitly release (e.g., in dealloc) in non-garbage collected environments.
-if you use copy then you still need to release that in dealloc.
-Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other
owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
Example:
#property (nonatomic, copy) NSArray *myArray;
#synthesize myArray;

Atomic property can be accessed by only one thread at a time. It is thread safe. Default is atomic .Please note that there is no keyword atomic
Nonatomic means multiple thread can access the item .It is thread unsafe
So one should be very careful while using atomic .As it affect the performance of your code

prefer this links about properties in objective-c in iOS...
https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html

Related

What happens if we use both strong and retain for the same IBOutlet?

Can we use Strong and Retain for the same IBOutlet?
What happens if we do so?
Something like this
#property (retain, strong) NSNumber *property;
If you're using ARC, you will get the same effect. No matter if you're using strong or retain attribute.
From Apple doc
Instead of you having to remember when to use retain, release, and autorelease, ARC evaluates the lifetime requirements of your objects and automatically inserts appropriate memory management calls for you at compile time. The compiler also generates appropriate dealloc methods for you. In general, if you’re only using ARC the traditional Cocoa naming conventions are important only if you need to interoperate with code that uses manual reference counting.
Can we use Strong and Retain for the same IBOutlet? What happens if we do so?
[Emphasis added]
Assuming ARC, but it probably makes no difference:
Yes, and the compiler just behaves as if you only typed one of them (which are synonyms).
Indeed the compiler doesn't seem to mind how often you type an attribute as long as you write an incompatible combination, e.g.:
#property (copy, copy, copy, copy) NSNumber *copiedProperty;
#property (retain, strong, retain, strong) NSNumber *strongProperty;
are accepted (and produce identical code to the equivalent declarations containing just one copy or retain/strong)! But:
#property (weak, copy) NSNumber *willProduceAnErr;
is not because it's meaningless.

What happens when a object is assigned to another object?

For example:
myVC.bunnies = self.myBunnies;
or
[self getBunniesWithCompletion:^(NSArray *bunnies) {
self.myBunnies = bunnies;
}];
Is the object copied, or it's just its reference that is copied, and if it gets destroyed everything will break?
The property is declared like so:
#property (strong, nonatomic) NSArray *myBunnies;
When you do this assignment, a reference is copied, and a reference count is incremented. All of this is done implicitly through ARC, because you declared your property strong.
If you would like a copy to be made, change the declaration to
#property (copy, nonatomic) NSArray *myBunnies
This would be more expensive, but the array inside your object would be insulated from the array passed into the setter.
It totally depends on the way you declared the property:
#property(strong) : the object reference count is increased, meaning that the object self keeps a reference to the affected object so that this object is not released (until the reference has been released by setting it to nil)
#propery(weak) : the object reference is simply assigned but the reference count is not increased, meaning that self does not retain a reference to it
#property(copy) : the object is copied (using <NSCopying>'s copy method) and thus a new instance is stored, independant from the first one
I strongly recommand you to read the Advanced Memory Managment Programming Guide in the Apple Doc. It is not totally up-to-date as some parts of the doc still describe the way it works before ARC was the standard, but it's still always interesting to read to understand those mecanisms.

Use ARC in simple class object-c

I want to use ARC in my simple class where I store some values to pass into another class. And I want to know what reference I have to use in the property. To use it in ARC, I have this:
#interface MyItem : NSObject
#property (retain) NSString *valueID;
#property (retain) NSString *itName;
#property (retain) NSDate *creationDate;
#property (assign) float rating;
This is a very simple class, and I want to know how to use it in ARC. What reference do I have to use? Do I have to use a copy for the NSString etc?
EDIT:
If I have a UIViewController, and I want to use a property for NSString and for MyItem object like this:
#interface MyViewController : UIViewController
#property (nonatomic, retain) NSString *myString;
#property (nonatomic, retain) MyItem *newItem;
What reference do I have to use for NSString and for MyItem object?
You want to use strong instead of retain. And yes, you should still use copy for NSStrings. The use of copy has nothing to do with ARC; you want copy because if someone assigns an NSMutableString to your property you don't want the string changing behind your back. Using copy gives you an immutable snapshot of the mutable string at the point where the assignment took place.
This is the recommended way to declare the properties in your view controller example:
#interface MyViewController : UIViewController
#property (nonatomic, copy) NSString *myString;
#property (nonatomic, strong) MyItem *newItem;
The NSString could be declared as strong as well, but copy is almost always preferable for strings (and really any immutable type that has a mutable variant, e.g. arrays, dictionaries, etc).
(nonatomic, strong) is what i use but here is the documentation
or for quick reference
Setter Semantics
These attributes specify the semantics of a set accessor. They are
mutually exclusive.
strong Specifies that there is a strong (owning) relationship to the
destination object.
weak Specifies that there is a weak (non-owning) relationship to the
destination object.
If the destination object is deallocated, the property value is
automatically set to nil.
(Weak properties are not supported on OS X v10.6 and iOS 4; use assign
instead.)
copy Specifies that a copy of the object should be used for
assignment.
The previous value is sent a release message.
The copy is made by invoking the copy method. This attribute is valid
only for object types, which must implement the NSCopying protocol.
assign Specifies that the setter uses simple assignment. This
attribute is the default.
You use this attribute for scalar types such as NSInteger and CGRect.
retain Specifies that retain should be invoked on the object upon
assignment.
Atomicity
You can use this attribute to specify that accessor methods are not
atomic. (There is no keyword to denote atomic.)
nonatomic Specifies that accessors are nonatomic. By default,
accessors are atomic.

iOS property declaration clarification

This is a two part question in hopes that I can understand more about the topic.
1) It seems to me that you have two popular options for declaring a property for a class in objective c. One is to add the property to the header's class body eg.
#interface MyClass : NSObject {
NSArray *myArray;
}
Or you can add it after the #interface body and before the #end statement like so.
#interface MyClass : NSObject {
//
}
#property (nonatomic, retain) NSArray *myArray;
What is the difference between these two "styles" and when do you choose one over the other?
2) after the #property you find options such as (nonatomic, retain). What are those for and why/when do you use different options?
Here are the only property modifiers that Xcode recognizes:
nonatomic (does not enforce thread safety on the property, mainly for use when only one thread shall be used throughout a program)
atomic (enforces thread safety on the property, mainly for use when multiple threads shall be used throughout a program) (default)
retain / strong (automatically retains / releases values on set, makes sure values do not deallocate unexpectedly) (default if ARC and object type)
readonly (cannot set property)
readwrite (can both set and get property) (default)
assign / unsafe_unretained (no memory management shall be done with this property, it is handled manually by the person assigning the value) (default if not ARC or object type)
copy (copies the object before setting it, in cases where the value set must not change due to external factors (strings, arrays, etc).
weak (automatically zeroes the reference should the object be deallocated, and does not retain the value passed in)
getter=method (sets the selector used for getting the value of this property)
setter= method (set the selector used for setting the value of this property)
1) #property is a special way to define getter- and setter-methods, or as we call them accessors in Objective-C. Your first snippet just declares an array for which you have to declare and write accessors yourself. For example setMyArray: and myArray.
Using #property will declare your accessors for you and is equivalent to declaring setMyArray: and myArray yourself. It is the preferred way to declare accessors since Objective-C 2.0. Note that you still have to declare the property (in your case myArray) yourself.
2) You first need to know about #synthesize. Remember that #property DECLARES the accessors for your property, #synthesize will IMPLEMENT them. When you use an #property in your #interface you mostly likely write an #synthesize in #implementation. Using #synthesize is equivalent to implementing setMyArray: and myArray.
The attributes (nonatomic, retain) tell the compiler, among others, how the memory management should work and therefore how the methods will be implemented. Note that you never actually see these accessors, but be assured that they are there and ready for you to be used.
To read more on that topic I recommend reading Section 9 on Properties from the following Tutorial or buy a Book that covers an Introduction to Objective-C.
Also you should familiarize yourself with at least the following attributes:
Access
Choose readwrite (default) or readonly. If readonly is set, ONLY the getter methods will be available.
Setter Memory Management
assign (default), simply assigns the new value. You mostly likely only use this with primitive data types.
retain, releases the old value and retains the new. If you use the garbage collector, retain is equivalent to assign. Why? The manual release of the old value will be done by the garbage collector.
copy will copy the new value and release the old value. This is often used with strings.
Threading
atomic (default) will ensure that the setter method is atomic. This means only one thread can access the setter at once.
nonatomic, use this when you don't work with threads.
This post gives you a good introduction to memory management and assign, retain and copy.
Properties are basically the accessor methods. They define the scope of the variable.
First case as given above,the variable is not accessible in other classes whereas by declaring a property as in the second case,variable is accessible in other classes also.
Also, they are useful for memory management.
First one will be private declaration and will not be accessible by other classes if you do not define the second one. Second is used together with #synthesize in .m module , and setter/getter's are created for you by the compiler. You can still define your own getter or setter with this. In this case all iVars defined in #property can be accessed by other classes.Retain/release operations are done automatically.
You should read Apple documentation for more details.
please check:
What's the difference between the atomic and nonatomic attributes?
Properties are basically the accessor methods. They define the scope of the variable. by default access specifior of variable is protected and properties set its Specifier from protected to Public

Objective-C 101 (retain vs assign) NSString

A 101 question
Let's say i'm making database of cars
and each car object is defined as:
#import <UIKit/UIKit.h>
#interface Car:NSObject{
NSString *name;
}
#property(nonatomic, retain) NSString *name;
Why is it #property(nonatomic, retain) NSString *name; and not #property(nonatomic, assign) NSString *name;?
I understand that assign will not increment the reference counter as retain will do. But why use retain, since name is a member of the todo object the scope of it is to itself.
No other external function will modify it either.
There's no such thing as the "scope of an object" in Objective-C. Scope rules have nothing to do with an object's lifetime — the retain count is everything.
You usually need to claim ownership of your instance variables. See the Objective-C memory management rules. With a retain property, your property setter claims ownership of the new value and relinquishes ownership of the old one. With an assign property, the surrounding code has to do this, which is just as mess in terms of responsibilities and separation of concerns. The reason you would use an assign property is in a case where you can't retain the value (such as non-object types like BOOL or NSRect) or when retaining it would cause unwanted side effects.
Incidentally, in the case of an NSString, the correct kind of property is usually copy. That way it can't change out from under you if somebody passes in an NSMutableString (which is valid — it is a kind of NSString).
and don't forget to access it via
self.name = something;
because
name = something;
will not care about the generated setter/getter methods but instead assign the value directly.
Without retain there is no guarantee the NSString* you are setting name with will live any longer than the assignment statement itself. By using the retain property for the synthesized setter you're allowing it to tell the memory management system that there is at least one more object interested in keeping the NSString* around.
For those who are looking for it, Apple's documentation on property attributes is here.
The self. in:
self.name = something;
is important! Without it, you are accessing the variable directly and bypassing the setter.
The older style (correct me if I am wrong) would have been:
[self setName:something];
Anyway, this notation was the (vaguely familiar sounding) advice that I really needed when I went looking for proper #properties on NSStrings. Thanks Axel.
After reading so many Articles, SO posts and made demo apps to check Variable property attributes, I decided to put all the attributes information together
atomic //default
nonatomic
strong=retain //default
weak= unsafe_unretained
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
so below is the detailed article link where you can find above mentioned all attributes, that will defiantly help you.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
retain = strong
it is retained, old value is released and it is assigned
retain specifies the new value should be sent -retain on assignment and the old value sent -release
retain is the same as strong.
apple says if you write retain it will auto converted/work like strong only.
methods like "alloc" include an implicit "retain"
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
assign
assign is the default and simply performs a variable assignment
assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
I would use assign for C primitive properties and weak for weak references to Objective-C objects.
Example:
#property (nonatomic, assign) NSString *address;
#synthesize address;
Google's Objective-C Style Guide covers this pretty well:
Setters taking an NSString, should always copy the string it accepts.
Never just retain the string. This avoids the caller changing it under you without your knowledge. Don't assume that because you're accepting an NSString that it's not actually an NSMutableString.
Would it be unfortunate if your class got this string object and it then disappeared out from under it? You know, like the second time your class mentions that object, it's been dealloc'ed by another object?
That's why you want to use the retain setter semantics.

Resources