When to use strong, weak, retain etc? [duplicate] - objective-c

There are two new memory management attributes for properties introduced by ARC, strong and weak.
Apart from copy, which is obviously something completely different, are there any differences between strong vs retain and weak vs assign?
From my understanding, the only difference here is that weak will assign nil to the pointer, while assign won't, which means the program will crash when I send a message to the pointer once it's been released. But if I use weak, this won't ever happen, because message send to nil won't do anything.
I don't know about any differences between strong and retain.
Is there any reason why should I use assign and retain in new projects, or are the kind of being deprecated?

After reading so many articles Stackoverflow posts and demo applications to check variable property attributes, I decided to put all the attributes information together:
atomic //default
nonatomic
strong=retain //default
weak
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
Below is the detailed article link where you can find above mentioned all attributes, that will definitely help you.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
1.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;
2.weak
-
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).
3.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;
4.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;

From the Transitioning to ARC Release Notes (the example in the section on property attributes).
// The following declaration is a synonym for: #property(retain) MyClass *myObject;
#property(strong) MyClass *myObject;
So strong is the same as retain in a property declaration.
For ARC projects I would use strong instead of retain, I would use assign for C primitive properties and weak for weak references to Objective-C objects.

nonatomic/atomic
nonatomic is much faster than atomic
always use nonatomic unless you have a very specific requirement for atomic, which should be rare (atomic doesn't guarantee thread safety - only stalls accessing the property when it's simultaneously being set by another thread)
strong/weak/assign
use strong to retain objects - although the keyword retain is synonymous, it's best to use strong instead
use weak if you only want a pointer to the object without retaining it - useful for avoid retain cycles (ie. delegates) - it will automatically nil out the pointer when the object is released
use assign for primatives - exactly like weak except it doesn't nil out the object when released (set by default)
(Optional)
copy
use it for creating a shallow copy of the object
good practice to always set immutable properties to copy - because mutable versions can be passed into immutable properties, copy will ensure that you'll always be dealing with an immutable object
if an immutable object is passed in, it will retain it - if a mutable object is passed in, it will copy it
readonly
use it to disable setting of the property (prevents code from compiling if there's an infraction)
you can change what's delivered by the getter by either changing the variable directly via its instance variable, or within the getter method itself

As far as I know, strong and retain are synonyms, so they do exactly the same.
Then the weak is almost like assign, but automatically set to nil after the object, it is pointing to, is deallocated.
That means, you can simply replace them.
However, there is one special case I've encountered, where I had to use assign, rather than weak. Let's say we have two properties delegateAssign and delegateWeak. In both is stored our delegate, that is owning us by having the only strong reference. The delegate is deallocating, so our -dealloc method is called too.
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething];
[delegateAssign doSomething];
}
The delegate is already in deallocation process, but still not fully deallocated. The problem is that weak references to him are already nullified! Property delegateWeak contains nil, but delegateAssign contains valid object (with all properties already released and nullified, but still valid).
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething]; // Does nothing, already nil.
[delegateAssign doSomething]; // Successful call.
}
It is quite special case, but it reveal us how those weak variables work and when they are nullified.

Clang's document on Objective-C Automatic Reference Counting (ARC) explains the ownership qualifiers and modifiers clearly:
There are four ownership qualifiers:
__autoreleasing
__strong
__*unsafe_unretained*
__weak
A type is nontrivially ownership-qualified if it is qualified with
__autoreleasing, __strong, or __weak.
Then there are six ownership modifiers for declared property:
assign implies __*unsafe_unretained* ownership.
copy implies __strong ownership, as well as the usual behavior of copy semantics on the setter.
retain implies __strong ownership.
strong implies __strong ownership.
*unsafe_unretained* implies __*unsafe_unretained* ownership.
weak implies __weak ownership.
With the exception of weak, these modifiers are available in non-ARC modes.
Semantics wise, the ownership qualifiers have different meaning in the five managed operations: Reading, Assignment, Initialization, Destruction and Moving, in which most of times we only care about the difference in Assignment operation.
Assignment occurs when evaluating an assignment operator. The
semantics vary based on the qualification:
For __strong objects, the new pointee is first retained; second, the lvalue is loaded with primitive semantics; third, the new pointee is stored into the lvalue with primitive semantics; and finally, the old pointee is released. This is not performed atomically; external synchronization must be used to make this safe in the face of concurrent loads and stores.
For __weak objects, the lvalue is updated to point to the new pointee, unless the new pointee is an object currently undergoing deallocation, in which case the lvalue is updated to a null pointer. This must execute atomically with respect to other assignments to the object, to reads from the object, and to the final release of the new pointee.
For __*unsafe_unretained* objects, the new pointee is stored into the lvalue using primitive semantics.
For __autoreleasing objects, the new pointee is retained, autoreleased, and stored into the lvalue using primitive semantics.
The other difference in Reading, Init, Destruction and Moving, please refer to Section 4.2 Semantics in the document.

To understand Strong and Weak reference consider below example,
suppose we have method named as displayLocalVariable.
-(void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
}
In above method scope of myName variable is limited to displayLocalVariable method, once the method gets finished myName variable which is holding the string "ABC" will get deallocated from the memory.
Now what if we want to hold the myName variable value throughout our view controller life cycle. For this we can create the property named as username which will have Strong reference to the variable myName(see self.username = myName; in below code), as below,
#interface LoginViewController ()
#property(nonatomic,strong) NSString* username;
#property(nonatomic,weak) NSString* dummyName;
- (void)displayLocalVariable;
#end
#implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
self.username = myName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Now in above code you can see myName has been assigned to self.username and self.username is having a strong reference(as we declared in interface using #property) to myName(indirectly it's having Strong reference to "ABC" string). Hence String myName will not get deallocated from memory till self.username is alive.
Weak reference
Now consider assigning myName to dummyName which is a Weak reference, self.dummyName = myName;
Unlike Strong reference Weak will hold the myName only till there is Strong reference to myName.
See below code to understand Weak reference,
-(void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
self.dummyName = myName;
}
In above code there is Weak reference to myName(i.e. self.dummyName is having Weak reference to myName) but there is no Strong reference to myName, hence self.dummyName will not be able to hold the myName value.
Now again consider the below code,
-(void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
self.username = myName;
self.dummyName = myName;
}
In above code self.username has a Strong reference to myName, hence self.dummyName will now have a value of myName even after method ends since myName has a Strong reference associated with it.
Now whenever we make a Strong reference to a variable it's retain count get increased by one and the variable will not get deallocated retain count reaches to 0.
Hope this helps.

Strong:
Property will not Destroy but Only once you set the property to nil will the object get destroyed
By default all instance variables and local variables are strong pointers.
You use strong only if you need to retain the object.
We generally use strong for UIViewControllers (UI item's parents)
IOS 4 (non-ARC) We Can Use Retain KeyWord
IOS 5(ARC) We Can Use Strong Keyword
Example:
#property (strong, nonatomic) ViewController *viewController;
#synthesize viewController;
Weak
By Default automatically get and set to nil
We generally use weak for IBOutlets (UIViewController's Childs) and delegate
the same thing as assign, no retain or release
Example :
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#synthesize myButton;

The differences between strong and retain:
In iOS4, strong is equal to retain
It means that you own the object and keep it in the heap until don’t point to it anymore
If you write retain it will automatically work just like strong
The differences between weak and assign:
A “weak” reference is a reference that you don’t retain and you keep it as long as someone else points to it strongly
When the object is “deallocated”, the weak pointer is automatically set to nil
A "assign" property attribute tells the compiler how to synthesize the property’s setter implementation

Related

ARC: property vs ivar: copy, weak

From reading Property vs. ivar in times of ARC, I understand that ARC will use the __strong ownership qualifier when I directly get or set a strong property's autosynthesized associated instance variable but will neither call custom getters or setters nor trigger KVO.
But, if I declare a property as weak like so:
#property (weak, nonatomic) id <XYZExampleViewDelegate> delegate;
Will the autosynthesized associated instance variable take on the __weak ownership qualifier?
For example, will _delegate = delegate (vs self.delegate = delegate) in my implementation of
- (id)initWithDelegate:(id <XYZExampleViewDelegate>)delegate
perform assignment according to the __weak qualification?
What about for a property declared with copy?
Yes, the property modifier weak implies __weak ownership. A property's associated instance variable (or backing ivar) is created with the ownership qualifier implied by the property's modifier. See Clang documentation on ARC property declarations for a list of property modifiers and which ownership qualifiers they imply.
The property modifier copy implies __strong ownership. So, when setting the backing ivar directly, the new pointee is retained but not copied. To copy it, use the setter.

Overriding setter methods (strong vs. assign) using ARC

When defining a strong property in an interface, like so:
#property (nonatomic, strong) UIColor *petColor;
It is no longer required to add #synthesize, or #dynamic, or to manually define the internal ivar as _petColor, this all just works. The setters/getters are automatically generated, and you can access _petColor internally without any additional code.
However, I'm a little confused as to how (if at all), when overriding a setter, ARC knows whether to insert the retain/release calls depending on whether the property is strong or weak? For example, if I have two properties:
#property (nonatomic, strong) UIColor *petColor;
#property (nonatomic, weak) SomeClass *petDelegate;
If I want to override the setters for these properties, it seems they would be almost exactly the same?
- (void)setPetColor:(UIColor *)theColor {
if (![theColor isEqual:petColor]) {
_petColor = theColor;
}
}
- (void)setPetDelegate:(SomeClass *)theDel {
if (theDel != petDelegate) {
_petDelegate = theDel;
}
}
Is this correct? And if so, is ARC automatically inserting the proper retain/release calls in both of those setters, or only in the overridden setter for the strong property?
Further: Does the weak property behavior differ, in this situation, from the assign property behavior?
It's even simpler than that. When synthesizing, the instance variables get the respective qualifiers:
#implementation MyClass {
// this is what is added by the auto synthesize
UIColor * __strong _petColor;
SomeClass * __weak _petDelegate;
}
So when you assign to the instance variables using own setters, everything is fine, except for the copy qualifier. That one cannot be used for an instance variable, so then assign a copy to the instance variable.
Regarding assign (or the equivalent unsafe_unretained) for object properties, the instance variable would just be a pointer, and be synthesized to
SomeClass * __unsafe_unretained _petDelegate;
So if the object assigned to the property is deallocated, the pointer would not be set to nil as with weak, but point to where the deallocated object lived before. That may lead to crashes. As a rule of thumb, if you write your code for iOS 5 or later, always use weak instead of assign or unsafe_unretained on object properties.
Setting the strong, weak, or assign attributes of a property tells the compiler the storage class of the underlying data. If that is an auto-generated iVar, then it maps as following:
strong -> __strong
weak -> __weak
assign -> __unsafe_unretained
If you don't use an auto-generated iVar, then whatever data you have feeding the property is expected to conform to those storage class mappings.
See: Objective-C Automatic Reference Counting (ARC) : Property declarations

Can anyone explain the synthesize process when using Objective-C?

I realize that it automatically creates a setter & getter for you but I'm uncertain how the setter actually "looks".
Also, why is it recommended that we say #synthesize someObject = _someObject; instead of just #synthesize someObject;?
Easy bit first: you don't need to #synthesize at all any more. If you have an #property and you don't synthesise it then one is implied, of the form #synthesize someObject = _someObject;. If you left off the = _someObject then you would have the same thing as #synthesize someObject = someObject;. The underscore version is therefore preferred because Apple has swung back to advocating underscores for instance variables and because it's consistent with the implicit type of synthesise.
The exact form of setter and getter will depend on the atomic, strong, unsafe_unretained, etc flags but sample nonatomic strong setter, pre-ARC is:
- (void)setProperty:(NSString *)newPropertyValue
{
[newPropertyValue retain];
[_property release];
_property = newPropertyValue;
}
Note the retain always occurs before the release. Otherwise the following (which you would arrive at in a roundabout fashion rather than ever writing directly):
self.property = _property;
Would lead to _property potentially being deallocated before it was retained.
A sample getter (also pre-ARC) is:
- (NSString *)property
{
return [[property retain] autorelease];
}
The retain ensures that the return value will persist even if the object it was queried from is deallocated. The autorelease ensures you return a non-owning reference (ie, the receiver doesn't explicitly have to dispose of the thing, it can just forget about it when it's done). If the thing being returned is immutable but the instance variable is mutable then it's proper form to copy rather than retain to ensure that what you return doesn't mutate while someone else is holding onto it.
Check leture 3 of iPad and iPhone Application itunes
_someObj replace a memory location for store your object(a pointer).
Xcode 4 auto #synthesize anyObject = _anyObject; -> So you don't need to write #synthesize anymore.
If you have some other object or _anyMemoryLocation write before in your.m file, you can use #synthesize yourObj = _anyMemeryLocation if you don't want rewrite all name in your.m file.
Setter and getter 2 methods use to set or get your object's value outside or inside your class:
-(void)setObject:(ObjectType *) object;
-(void)getObject:(ObjectType *) object;
The key nonatomic auto generate setter and getter for you.
If you want to implement more method went setObject, you can rewrite it in your.m file
-(void)setObject:(ObjectType *) object{
_object = object; //rewrite setter can done anywhere in your.m file
//Add more method
}

custom class initializers with ARC - self.name or name?

when defining a Person class with ARC,
should i use self.fullname or just fullname in the initializer?
if i use fullname will the passed strings be retained?
if i use self.fullname i must define a setter or a property? should i use strong?
coming from a pre ARC way of thinking, i'm trying to wrap my head around the changes ARC suggests.
With ARC, these behave the same way, except that self.fullname will pass through the setter. The default setter will give you KVO-compliance. But otherwise, there is no difference.
Yes they will, if the pointers have been declared strong.
To use self.fullname = ... you must define a setter. For NSStrings and other classes which have mutable variants, it is usually recommended to use (copy).
In initializers, I'd advise against invoking any methods on self, because the object is in that unusual state where it lacks self-consistency. For the simple example you give, it doesn't make a difference right away. But if you later define your own -setFullname: method that reads or writes any other part of your object, invoking self.fullname = from your initializer will cause problems because the object isn't fully-formed yet.
I think the available answers need some clarification.
The long answer to your question
Look at this header:
Person : NSObject {
NSString *name; // better to call this _name to not confuse it with the property
// and even more better to not use an ivar, but only a property
}
#property (strong) NSString *name;
You have an instance variable. Usually you'd call your ivar the same as the property with an underscore, but often you'll find the ivar and the property have the same name.
It is also possible to only declare a property, in this case, the compiler will automatically insert an ivar with an underscore for you!
Now it is important to understand, that there is one major difference between name = #"John Smith" and self.name = #"John Smith", the first one directly sets the instance variable (aka _name = #"John Smith", disregarding memory management and (without ARC) creating a leak if the former value was not nil. Using the self-dot-syntax (self.name) uses the automatically generated accessor (=setter method), which respects the chosen memory management (typically retain or strong or copy).
Before properties and before ARC an object setter would have looked like this:
-(void)setName:(NSString*)newName {
if(newName != name) {
[name release];
name = newName;
[newName retain];
}
}
that means, the old iVar value is released and the new iVar value retained. All balanced and fine.
Now, with ARC and synthesized accessors (properties), you do not have to care about all this. While Properties synthesize acessors, ARC synthesizes and balanced retain/release calls based on an analysis of your code. So ARC and properties are not necessarily requiring each other, because they synthesize different aspects (note for example the different syntax "__weak" at the ivar declaration and "(weak)" at the property declaration?). But it's useful to know how it used to work, because now you'll see that there is a major difference between
name = #"John Smith"; // directly access ivar, the old value is never released
// your program is leaking if you're not using ARC
and going through the synthesized accessor
self.name = #"John Smith"; // old ivar released, new ivar set, all okay
The short answer to your question
do not use an ivar and a property if there is no need for both
self.property = newValue sets the new value by its setter method
ivar = newValue sets the new value directly, bypassing any setter method
it is definitely recommended to use the accessors and to not set ivars directly if there is a setter method (in other words: if you have a property, use its setter by calling self.property = newValue)

what will happen if assign a weak property to a strong property?

In old term, it's about assign a autoreleased property to a retain property. What will happen if do that, something like the following does.
#property(strong, nonatomic) NSString *new;
...
NSString *old = [NSString stringWithFormat:#"%# %#"), #"hello", #"world"];
new = old;
adding to my comment on your question:
read this
Variable Qualifiers
It describes the different types of lifetime qualifiers you can declare variables with and gives examples of each.
Edit with relevant bits:
The lifetime qualifiers you can use are:
__strong
__weak
__unsafe_unretained
__autoreleasing
Their descriptions are in the docs but I will go into the first 2.
__strong is the default type (when you don't specify one) and it will increase the retain count of the object by 1. As long as there is a strong pointer pointing to an object, it will remain alive.
__weak does not increase the retain count of an object and will not keep it alive. If there are no strong references pointing to the same object, the weak pointer will be set to nil automatically. (__unsafe_unretained is actually almost the same as weak but they are left dangling instead of being set to nil).
If you create an object immediately assigned to a weak pointer, it will be instantly deallocated since there are no strong references to it.
Sample Code from docs:
NSString * __weak string = [[NSString alloc] initWithFormat:#"First Name: %#", [self firstName]];
NSLog(#"string: %#", string);
The value of string will be null when trying to print it in this case.
You can only use a weak pointer if the object you want to reference with it already has at least one strong reference to it. Otherwise the (new) object will be deallocated instantly.