您的位置:首页 > 移动开发 > IOS开发

IOS Dev Intro - Variable property attributes or Modifiers in iOS

2016-07-12 10:37 489 查看
http://stackoverflow.com/questions/8927727/objective-c-arc-strong-vs-retain-and-weak-vs-assign

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;


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.


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

16down
vote
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.

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

16down
vote
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.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: