ARC: property vs ivar: copy, weak - objective-c

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.

Related

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

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

Are declared property attributes overridden when implementing custom accessor methods?

Suppose I declare a property like so
#property (nonatomic, copy) NSObject *property;
Then I create a custom setter method
- (void) setProperty:(NSObject *)property
{
_property = property;
// Some more code here
}
Does the compiler interpret the copy keyword so that this setter function is equivalent to this?
_property = [property copy];
Or is it my responsibility to write it this way so that the keyword matches the behavior?
From "4.1.1 Property declarations" in the Clang/ARC documentation
(emphasis added):
copy implies __strong ownership, as well as the usual behavior of copy semantics on the setter.
...
A property’s specified ownership is preserved in its metadata, but
otherwise the meaning is purely conventional unless the property is
synthesized.
If a property is synthesized, then the associated instance variable is
the instance variable which is named, possibly implicitly, by the
#synthesize declaration. If the associated instance variable already
exists, then its ownership qualification must equal the ownership of
the property; otherwise, the instance variable is created with that
ownership qualification.
So in your case, with a custom setter, declaring the property as "copy" implies that the associated
instance variable _property is __strong but nothing else.
It is your responsibility that the setter actually makes a copy, for example:
- (void) setProperty:(NSObject *)property
{
_property = [property copy];
// Some more code here
}

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

Autosynthesized property 'delegate' will use synthesized instance variable '_delegate', not existing instance variable 'delegate'

I'm following the guide here to create a custom delegate. It runs fine but I get the following warning in xcode
DetailViewController.m:23:1: Autosynthesized property 'delegate' will
use synthesized instance variable '_delegate', not existing instance
variable 'delegate'
Can anyone advise how to get rid of the warning
The most idiomatic way to handle this situation is simply to remove your delegate ivar declaration. If you were using your delegate ivar, you should use the implicit ivar _delegate instead.
Why does this work?
As of Xcode 4.4 (LLVM Compiler 4.0), instance variables and accessor methods are synthesized automatically for a property if the #synthesize directive is not used explicitly for that property. As Apple's documentation on encapsulation states
By default, [...] accessor methods are synthesized automatically for you by the compiler, so you don’t need to do anything other than declare the property using #property in the class interface.
The ivar that is used for a property (which is gotten and set by the automatically synthesized property accessor methods) is named _<propertyName> (i.e. the ivar's name is the property's name prefixed with an underscore).
In this case the property name is delegate, so the the ivar that is used is _delegate. This is already happening in your code. When you call -delegate and -setDelegate:, this ivar _delegate will be gotten and set.
However, you've also declared your own ivar delegate. Of course, the ivar you explicitly declared (delegate) will not be gotten and set by the instance methods -delegate and -setDelegate: since the automatically synthesized ivar (_delegate) is being gotten and set. However, (almost always--if it wasn't, your code is ambiguous) your intent was for your ivar delegate to be the thing that your property's accessors would get and set. Luckily, the compiler is clever enough to notice what you've done, and that's why it is emitting this warning:
warning: autosynthesized property 'delegate' will use synthesized instance variable '_delegate', not existing instance variable 'delegate' [-Wobjc-autosynthesis-property-ivar-name-match]
It's telling you that your property delegate will use the automatically synthesized ivar _delegate rather than the ivar that you explicitly declared, delegate.
So if you simply delete your delegate ivar, the compiler will stop emitting this warning. If you were using the delegate ivar directly (not through the property), start using _delegate instead.
A minor variation on this option is to explicitly declare the same ivar (_delegate) that the automatic synthesis of the delegate property is creating. You can do this by replacing
#interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> delegate
//...
}
#end
with
#interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> _delegate
//...
}
#end
This works because automatic synthesis of a property will always use an ivar whose name is the property's name prefixed with an underscore. If no such ivar exists, the ivar will be generated. If it does exist, it will be used.
If instead you would prefer that your property's accessors set and get your ivar delegate you can add an #synthesize directive to your class' #implementation to tell the compiler to do just this:
#implementation TheClass
//...
#synthesize delegate = delegate;
//...
#end
The line #synthesize delegate = delegate; tells the compiler to use the ivar delegate (the right hand of the assignment) in the accessors for the property delegate (the left hand side of the assignment).
You can also omit the right hand side of the #synthesize assignment and just write
#implementation TheClass
//...
#synthesize delegate;
//...
#end
This works because a property with a manual #synthesize which does not explicitly specify the ivar to be gotten and set by its accessors (such as #synthesize delegate;) will use an ivar with the same name as the property, NOT prefixed by an underscore. This has to do with backwards compatibility.
There's another method and this one worked for me:
#property (nonatomic, unsafe_unretained) id <MyDelegate> delegate;
You can then add this to the implementation without error:
#synthesize delegate;
Also: This is ARC compliant.

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.