what will happen if assign a weak property to a strong property? - objective-c

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.

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

In Objective-C, what does it mean to assign a weak to a strong within a block?

In Objective-C, what does it mean to assign a weak to a strong within a block? What's happening behind the scene?
e.g.
__weak __typeof(self) wself = self;
void (^cmd)() = ^(){
__strong __typeof(self) sself = wself;
if (!sself) return;
...
};
The intent here is two-fold:
First, is the use of:
__weak __typeof(self) wself = self;
This ensures that the cmd block does not maintain a strong reference to self. This ensures that, if cmd was an instance variable of the class, that you don't end up with a strong reference cycle. If you don't use this wself pattern, the class that has cmd as an instance variable would never be released and you'd leak the object that has cmd as an instance variable.
For more information, see the Avoid Strong Reference Cycles when Capturing self section of the Programming with Objective-C: Working With Blocks document.
Second, the use of the following within the block:
__strong __typeof(self) sself = wself;
if (!sself) return;
This ensures that, if the block starts execution, if wself was already deallocated, the block would quit. But if wself has not yet been deallocated, by assigning sself, you're making sure that the object will be retained during the execution of the block.
Also, if you reference any ivars in the block, be aware that you want to dereference them (because otherwise there is an implicit reference to self in the block, potentially leading to that strong reference cycle). But you cannot dereference ivars using a weak pointer (e.g. wself->someIvar is not permitted), but you can with this local strong pointer (e.g. sself->someIvar is ok). Generally you shouldn't be dereferencing ivars anyway, but rather use properties, but nonetheless it's another reason to use a local strong reference to self.
Often, you'll see this construct in conjunction with a class property (or an ivar):
#property (nonatomic, copy) void (^commandBlock)(void);
And, as a matter of convention, you'll generally see more descriptive variable names, weakSelf and strongSelf, thus:
__weak __typeof(self) weakSelf = self;
self.commandBlock = ^(){
__strong __typeof(self) strongSelf = weakSelf;
if (!strongSelf) return;
...
};
This weakSelf/strongSelf pattern is very common when you have your own block properties to your class and you want to (a) prevent strong reference cycles (aka retain cycles); but (b) want to ensure that the object in question cannot be deallocated in the middle of the execution of the block.
If you don't assign weak reference to a strong the object referenced by the weak reference can be deallocated in the middle of the block execution - something you might not expect. if you assign to strong the object is retained for as long as the strong reference is in scope (unless the object has already been deallocated prior to the assignment).
When you assign a weak reference to a strong compiler inserts Objective-C runtime function call into the code that increments the object reference counter as needed to retain it. When the strong variable goes out of scope (or earlier, after the last use of the strong variable) another call inserted by compiler decrements the reference counter.

More about property releasing

Maybe someone could explain the difference between property:
in .h file
#property(nonatomic,retain) NSString *someString;
#property(nonatomic,retain) NSString *someString2;
in .m file
#synthesize someString = _someString;
or
#synthesize someString2;
what is the difference for _someString and self.someString2 using in controller?
and in dealloc how i should release these property's
[_someString release];
AND
[self.someString2 release];
OR
_someString = nil;
_someString2 = nil;
synthesize someString = _someString;
This says synthesize the property someString but for direct access, use _somestring.
synthesize someString2;
This says synthesize the property someString2 but for direct access, use someString2.
Think of it as if the compiler is generating the iVars for you but in the first case the iVar is called _someString and the second is called someString2
This is a common usage (I recently moved to it) so that when you are dealing with the object directly (such as initialisers or in dealloc, where you should't use self) you can see instantly that when you write _someString = #"aString"; you are not going through the property methods that would apply the memory management types (such as retain, or copy). It used to be common that people would assign values directly, and then wonder why they weren't being retained.
[_someString release];
[_someString2 release];
Is sending the release method directly to the object.
self.someString = nil;
self.someString2 = nil;
Sends release through the property. In this case, There is no difference. There would be a difference if you were allocating objects: for example:
_someString = someOtherString;
Is a leak (except under ARC, which I will come to later), because you are just putting in a new object to the store, without releasing the current object.
self.someString = someOtherString;
does not leak anything, because the sythesized setter will release the current object before setting (and retaining) the new object.
I said I'd come to ARC. In which case you can't call release anyway, so the questions don't arise, but _someString = someOtherString is not a leak, because the compiler will deal with releasing the current object for you.
After:
property(nonatomic,retain) NSString *someString;
property(nonatomic,retain) NSString *someString2;
and:
#synthesize someString = _someString;
#synthesize someString2;
someString is a property backed by the instance variable _someString. Memory retention and release is managed by Obj-C.
Assignments to someString should use the form self.someString within the class, and must use <reference>.someString outside of it. Except within an initializer there should never be any assignments to a plain _someString.
Reading the value can use simply _someString within the class, but self.someString is also valid, and must use <reference>.someString outside of it.
Releasing the value must use the form self.someString = nil within the class, and <reference>.someString = nil outside of it.
someString2 is similar except it is backed by an automatically named instance variable, which happens to be called someString2.
#synthesize someString = _someString; Means you're making a property with a different name then the member variable it's associated with. This is fine. Typically they are same name. Here's an example when that isn't the case. So someString would be your property and _someString is your member variable.
As for [_someString release]; and [self.someString2 release]; what you're seeing is release being called on the member variable of your class(Which is _someString). [self.someString2 release] calls release on whatever the property returns. Keep in mind that properties can do more then just simply get and set. They are methods just like any other you might right.
Also, don't do [self.someString2 release]; Instead do self.someString2 = nil; That will release it on your behalf. That way it nils out the string. That will protect you from accessing bad memory incase the string is actually deallocated.
_someString = nil won't release your property.
In this case _someString and self._someString point to the exact same object, so you can release using either.
[_someString release];
AND
[self.someString2 release];
releases twice, that's wrong. Use
_someString = nil;
_someString2 = nil;
simply sets your ivars to nil, it doesn't release them, so that's again wrong.
Correct: either
self.someString = nil;
self.someString2 = nil;
or
[_someString release];
[_someString2 release];
I'd recommend the first one (dot-notation), as it does the right thing (you don't know what kind of code does a compiler generate when synthesizing your accessors...)

What is the rule of thumb for using #property(copy) vs. #property(retain)?

I wonder if there is a rule of thumb you follow, when deciding whether or not a given property in ObjectiveC should be a retain or copy?
How do you decide which it should be?
Typically you use copy for safety with classes which have mutable variants, like NSString, NSArray, the other collection classes, etc. To see why, consider what happens here...
Once upon a time,
#interface MyClass : NSObject
#property (retain) NSString *happyString;
- (void)rejoice;
#end
Then one day,
- (void)bigBadMethod {
MyClass *myObject = [[[MyClass alloc] init] autorelease];
NSMutableString *theString = [NSMutableString stringWithString:#"I'm happy!"];
myObject.happyString = theString; // this is allowed because NSMutableString inherits from NSString
[myObject rejoice]; // prints "I'm happy!"
when suddenly...
[theString setString:#"BRAAAAIIINNNSSSSS"];
[myObject rejoice]; // prints "BRAAAAIIINNNSSSSS"
}
And you wouldn't want that, would you? So use #property (copy) if you don't want to get mutated while you're not looking!
In a nutshell, assign vs retain vs copy determines how the synthesized accessors interact with the Objective-C memory management scheme:
assign is the default and simply performs a variable assignment
retain specifies the new value should be sent -retain on assignment and the old value sent release
copy specifies the new value should be sent -copy on assignment and the old value sent release.
Remember that retain is done on the created object (it increases the reference count) whereas copy creates a new object. The difference, then, is whether you want to add another retain to the object or create an entirely new object.

What happens to a property if its value is overwritten?

Lets suppose I created a property tempStr that is of NSString type.
I synthesized it obviously.
In one of my methods, I set the value of tempstr to be yellowcolor.
Then just after that I reinitialized tempStr with redcolor.
So I wanna know what happens to the memory of tempStr in this case.
Thanx.
It depends on what attribute you set for your property: retain, assign or copy.
#property (retain) NSString *tempStr: the old value (yellowcolor) would be released and the new value (redcolor) would be retained. The only exception is when yellowcolor == redcolor. Then nothing would happen, because old and new values are the same.
#property (assign) NSString *tempStr: there would be no release/retain operations. It is equal to changing just a pointer. So after this operations yellowcolor won't be released and you'll lost a reference to it (if there is no other reference to it in your code). So it can cause a memory leak.
#property (copy) NSString *tempStr: it's similar to retain but it call copy on new value instead of just retain, so it'd create a duplicate object in a memory. Considering NSString, it's equal to retain, because NSString is immutable, so there is no need to make a duplicate.
You can find some code examples here.
EDIT: As #Bavarious mentioned, copy is equal to retain only if you initialize this property with NSString. It won't be equal if you initialize it with NSMutableString, because this one is mutable, so the "proper" copy would be make.
A synthesized setter looks a bit like this:
- (void)setSomeString:(NSString *)newString
{
if ([newString isEqualToString:someString]) return;
[someString autorelease];
someString = [newString copy]; // or [newString retain], depends how you defined the property ...
}
So the old value is released when the new value is assigned to the pointer.