Can someone explain to me in detail when I must use each attribute: nonatomic, copy, strong, weak, and so on, for a declared property, and explain what each does? Some sort of example would be great also. I am using ARC.
Nonatomic
Nonatomic will not generate threadsafe routines thru #synthesize accessors. atomic will generate threadsafe accessors so atomic variables are threadsafe (can be accessed from multiple threads without botching of data)
Copy
copy is required 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.
Assign
Assign is somewhat the opposite to copy. When calling the getter of an assign property, it returns a reference to the actual data. Typically you use this attribute when you have a property of primitive type (float, int, BOOL...)
Retain
retain is required when the attribute is a pointer to a reference counted object that was allocated on the heap. Allocation should look something like:
NSObject* obj = [[NSObject alloc] init]; // ref counted var
The setter generated by #synthesize will add a reference count to the object when it is copied so the underlying object is not autodestroyed if the original copy goes out of scope.
You will need to release the object when you are finished with it. #propertys using retain will increase the reference count and occupy memory in the autorelease pool.
Strong
strong is a replacement for the retain attribute, as part of Objective-C Automated Reference Counting (ARC). In non-ARC code it's just a synonym for retain.
This is a good website to learn about strong and weak for iOS 5.
http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
Weak
weak is similar to strong except that it won't increase the reference count by 1. It does not become an owner of that object but just holds a reference to it. If the object's reference count drops to 0, even though you may still be pointing to it here, it will be deallocated from memory.
The above link contain both Good information regarding Weak and Strong.
nonatomic property means #synthesized methods are not going to be generated threadsafe -- but this is much faster than the atomic property since extra checks are eliminated.
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.
weak ownership means that you don't own it and it just keeps track of the object till the object it was assigned to stays , as soon as the second object is released it loses is value. For eg. obj.a=objectB; is used and a has weak property , than its value will only be valid till objectB remains in memory.
copy property is very well explained here
strong,weak,retain,copy,assign are mutually exclusive so you can't use them on one single object... read the "Declared Properties " section
hoping this helps you out a bit...
This link has the break down
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.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.
Great answers!
One thing that I would like to clarify deeper is nonatomic/atomic.
The user should understand that this property - "atomicity" spreads only on the attribute's reference and not on it's contents.
I.e. atomic will guarantee the user atomicity for reading/setting the pointer and only the pointer to the attribute.
For example:
#interface MyClass: NSObject
#property (atomic, strong) NSDictionary *dict;
...
In this case it is guaranteed that the pointer to the dict will be read/set in the atomic manner by different threads.
BUT the dict itself (the dictionary dict pointing to) is still thread unsafe, i.e. all read/add operations to the dictionary are still thread unsafe.
If you need thread safe collection you either have bad architecture (more often) OR real requirement (more rare).
If it is "real requirement" - you should either find good&tested thread safe collection component OR be prepared for trials and tribulations writing your own one.
It latter case look at "lock-free", "wait-free" paradigms. Looks like rocket-science at a first glance, but could help you achieving fantastic performance in comparison to "usual locking".
Related
I have a model class which has below properties.
#interface CountryModel : NSObject
#property (nonatomic) NSInteger id;
#property (nonatomic, strong) NSString *country;
#property (nonatomic, strong) NSString *dialCode;
#property (nonatomic) BOOL isInEurope;
#end
I'm getting the below data from web service.
{
"id": 123,
"country_name": "India",
"dialCode": "+91"
}
Then I'm binding values to the array, Now my question is how memory management will work for the model class? Because there are few has a strong reference. Can anyone explain me.
Simple answer: automatically (provided you haven't disable ARC)
Slightly longer answer (provided you haven't disabled ARC):
When you assign values to the properties country and dialCode of an instance of CountryModel then that instance will have strong references to the referenced NSString values.
If you assign a new value to either of these properties then the previous strong reference will be dropped and replaced by a strong reference to the new value.
When the instance of CountryModel is no longer strongly reference by anything then the strong references it contains will be dropped.
When a strong reference is dropped if there are no other strong references to the reference object then that object becomes reclaimable and the memory it occupies returned to the available memory pool.
Note: if an NSString reference refers to a literal string then the literal string itself is immortal and will never be reclaimed. If you are trying to gian an understanding of when memory is released by monitoring memory usage, tracking dealloc calls, etc. do not use literal strings as your test objects – it is best to use a user-defined type.
But I've disabled ARC... Then memory will get reclaimed when you manually instruct it to be. If you're getting leaks turning on ARC is your best choice, if you cannot then you've some debugging to do!
HTH
Addendum after comment
Trying to follow reference counts and expecting them to match with actual executing code doesn't work well as there are often references you do not know about in compiled code. For this reason you will see many writers discouraging tracking reference counts.
Instead think in terms of strong references making an ownership stake in an object, and as long as there is an owner the object survives.
This might seem to be essentially the same thing, but there is a subtle difference in how the two are viewed: the reference count belongs to the object; while the strong reference attribute, which asserts an ownership stake, is part of the belongs to the referencing variable.
In your comment example a has an ownership stake in the CountryModel object it references - the only ownership stake you have so far created to that object. The CountryModel object has ownership stakes in the objects that country and dialcode reference, but may not be the only such stakeholders – in that fragment we've no idea what other reference variables assert an ownership stake in the objects those two variables reference.
Later when you create temparray the object reference stored in a is copied into the array and temparray claims and ownership stake in the referenced CountryModel object – while a continues to assert its own ownership stake as well. So now you have two variables you have created asserting an ownership stake in the CountryModel object.
A similar explanation applies to b & c.
When there is no ownership stake claimed by any variable/property over an object then that object can be destroyed. As part of that destruction any variables/properties that are part of that object are destroyed and any ownership stakes they asserted over references stored in them are withdrawn.
If that process results in more objects having no more ownership stakes asserted over them then those objects too can be destroyed; the process continuing to destroy unwanted objects until the only remaining objects are those where some variable/property asserts an ownership stake over them.
HTH more than it confuses!
The book named Pro Multithreading and Memory Management for iOS and OS X writed that
Why does the object need to be registered in autoreleasepool in order to use the object via the __weak qualified variable? Because a variable, which is qualified with __weak, does not have a strong reference, the object might be disposed of at any point. If the object is registered in autoreleasepool, until #autoreleasepool block is left, the object must exist. So, to use the objects via __weak variable safely, the object is registered in autoreleasepool automatically.
I do not understand why __weak need the variable is exist. __weak does not retain the variable.if the variable is not exist.The __weak variable should be nil.Why this book say that "If the object is registered in autoreleasepool, until #autoreleasepool block is left, the object must exist".
And if it is registered in autoreleasepool .Which pool does it is registered?I do not alloc a autoreleasepool when I use __weak.Who can tell me why.
The book you are reading is at least confusing, and may be sometimes outright wrong, in its presentation of __weak and __autoreleasing qualifiers. (The book is a translation, this may account for the sometimes confusing language used.)
References stored into __weak qualified variables are not also automatically added to the autorelease pool, that is contrary to the purpose of weak variables.
What does happen is that under some circumstances when a reference is loaded from a weak variable it is placed in the autorelease pool by the compiler to avoid a race condition (between an object being released and its reference being loaded from a weak variable). You do not need to concern yourself, at least directly, with this - the compiler is simply insuring that a reference you have loaded from a weak variable is valid for the time you use it.
You can find other comments on this book in the question Objective-C - weak object is registered in autoreleasepool automatically?
HTH
I am new at objective-c.I have a question .I know little about Retain .All i know is Retaining an object creates a strong reference, and an object cannot be deallocated until all of its strong references are released. If two objects retain each other, neither object ever gets deallocated because the connection between them cannot be broken. In ARC we can not retain a object. But we can retain a property.
What is the difference between retaining a object and retaining a property.
Thank You
Happy coding.
After searching so many articles and links, 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
Many thanks to all the people who give best answers here!!
a property is retain, mean the class own the property NSObject, that's nothing about ARC. ARC just do auto release reference count.
As a new iOS programmer, I've had a slew of bugs to fix today, a few of them have been related to me using weak properties instead of strong.
I realise that a good programmer wouldn't have this problem and would only set the properties to strong that need to be, but nonetheless, in my newbie eyes, I can't see why I should use weak, it only adds the risk of problems.
In general, you should decide between weak, strong, assign, and copy by looking at the relationship between the class holding the property and the value of that property, and also the kind of the property being passed.
If the property being set is primitive, use assign (or do not use ownership qualifier at all)
If the property being set is a scalar, immutable object, use strong
If the property being set is a scalar, mutable object implementing NSCopying protocol, use copy
If the property being set is mutable, and the ownership is transferred to your object, use strong
If the property being set is a mutable object implementing NSCopying protocol, but the ownership remains with the caller, use copy
If the property being set is a back reference (i.e. a "to parent" property in a "child" object), use weak.
The concept of ownership is very important in reference counted memory models. This is the primary driving factor behind your decision. You need to decide where is the primary owner of an object, and give that owner a strong reference. If an ownership is shared among a group of objects, give them all a strong reference.
The most difficult situation is when objects could own each other, directly or indirectly. In this case you would be better off replacing "ownership" with "knows about", give all objects a common "top" owner who "owns" everybody, and model the "knows about" relationships with weak references.
weak and strong are very important to get right for memory management purposes.
strong will increase the reference counter for the pointer, and you effectively say that you own the object.
weak does not increase the reference counter, and the object can potentially disappear at any time. If you have a cyclic dependency, you should use weak to avoid a memory leak (two objects both having a strong reference to each other is a cyclic dependency and those objects will never be released).
You should always think about your memory management, but a good rule of thumb is that the property should always be strong, unless you positively know that it is retained elsewhere. Multiple objects can have a strong reference to the same object with no problems, as long as no cyclic references occur.
Some super basic rules of thumb:
If you want the object to stick around at least until you are finished with it, go with strong
If you can handle the object disappearing without it hurting you too bad (i.e it is the parent that created you that might be nice to know about but not super important) then use weak
if it is not an NSObject (so is an int, bool float or other primitive type) use assign.
A rule of thumb that I use is: if the object is retained somewhere else, use weak. The biggest thing for me is when using interface builder. If you have an IBOutlet, you can make it weak, because that object is taken care of in interface builder and in the XIB file
I'm new to Objective C. I have basic knowledge in C, including the concept of pointers. I have two basic questions:
Can someone explain the difference between assign,copy, and retain with some analogy?
How do you handle a function which returns pointer variable, and how do you perform messaging through a return pointer?
Updated Answer for Changed Documentation
The information is now spread across several guides in the documentation. Here's a list of required reading:
Cocoa Core Competencies: Declared property
Programming with Objective-C: Encapsulating Data
Transitioning to ARC Release Notes
Advanced Memory Management Programming Guide
Objective-C Runtime Programming Guide: Declared Properties
The answer to this question now depends entirely on whether you're using an ARC-managed application (the modern default for new projects) or forcing manual memory management.
Assign vs. Weak - Use assign to set a property's pointer to the address of the object without retaining it or otherwise curating it; use weak to have the property point to nil automatically if the object assigned to it is deallocated. In most cases you'll want to use weak so you're not trying to access a deallocated object (illegal access of a memory address - "EXC_BAD_ACCESS") if you don't perform proper cleanup.
Retain vs. Copy - Declared properties use retain by default (so you can simply omit it altogether) and will manage the object's reference count automatically whether another object is assigned to the property or it's set to nil; Use copy to automatically send the newly-assigned object a -copy message (which will create a copy of the passed object and assign that copy to the property instead - useful (even required) in some situations where the assigned object might be modified after being set as a property of some other object (which would mean that modification/mutation would apply to the property as well).
The Memory Management Programming Guide from the iOS Reference Library has basics of assign, copy, and retain with analogies and examples.
copy
Makes a copy of an object, and returns it with retain count of 1.
If you copy an object, you own the copy. This applies to any method that contains the word copy where “copy” refers to the object being returned.
retain Increases the retain count of an object by 1. Takes ownership of
an object.
release Decreases the retain count of an object by 1. Relinquishes
ownership of an object.
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"First",#"Second", nil];
NSMutableArray *copiedArray = [array mutableCopy];
NSMutableArray *retainedArray = [array retain];
[retainedArray addObject:#"Retained Third"];
[copiedArray addObject:#"Copied Third"];
NSLog(#"array = %#",array);
NSLog(#"Retained Array = %#",retainedArray);
NSLog(#"Copied Array = %#",copiedArray);
array = (
First,
Second,
"Retained Third"
)
Retained Array = (
First,
Second,
"Retained Third"
)
Copied Array = (
First,
Second,
"Copied Third"
)
assign
assign is a default property attribute
assign is a property attribute tells the compiler how to synthesize the property’s setter implementation
copy:
copy is required when the object is mutable
copy returns an object which you must explicitly release (e.g., in dealloc) in non-garbage collected environments
you need to release the object when finished with it because you are retaining the copy
retain:
specifies the new value should be sent “-retain” on assignment and the old value sent “-release”
if you write retain it will auto work like strong
Methods like “alloc” include an implicit “retain”