@property retain, assign, copy, nonatomic in Objective-C
The article linked to by MrMage is no longer working. So, here is what I've learned in my (very) short time coding in Objective-C:
nonatomic vs. atomic
- "atomic" is the default. Always use "nonatomic". I don't know why, but the book I read said there is "rarely a reason" to use "atomic". (BTW: The book I read is the BNR "iOS Programming" book.)
readwrite vs. readonly
- "readwrite" is the default. When you @synthesize, both a getter and a setter will be created for you. If you use "readonly", no setter will be created. Use it for a value you don't want to ever change after the instantiation of the object.
retain vs. copy vs. assign
- "assign" is the default. In the setter that is created by @synthesize, the value will simply be assigned to the attribute. My understanding is that "assign" should be used for non-pointer attributes.
- "retain" is needed when the attribute is a pointer to an object. The setter generated by @synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it.
- "copy" is needed 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.
When to use assign or retain in properties declaration?
Assign is usually used for primitive types, the compiler will create the setter such that all that is done is a simple assign operation.
Whereas setting a value on a property with the 'retain' (now called "strong" with ARC) qualifier causes your backing instance variable to take ownership of (in other words retain) the object that was set.
With objects, if you don't want to take ownership as described and you're using ARC, you would most likely want to use the 'weak' qualifier instead of 'assign'.
Clarification on assign, retain, copy, strong?
To reiterate, it does depend on context. In an non-ARC situation:
@property (nonatomic, copy) NSMutableArray *myArray
@property (nonatomic, copy) NSString *myString
@property (nonatomic, retain) UIColor *myColor
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) int myInt
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) BOOL myBOOL
The copy on myArray is to prevent modification by another "owner" of the object you set. In an ARC project, things change a bit:
@property (nonatomic, copy) NSMutableArray *myArray
@property (nonatomic, copy) NSString *myString
@property (nonatomic, strong) UIColor *myColor
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) int myInt
//Note the change to an int rather than a pointer to an int
@property (nonatomic, assign) BOOL myBOOL
The change is primarily to myColor in your situation. You wouldn't use retain
as you aren't managing reference counting directly. The strong
keyword is a way of asserting "ownership" of the property and similar to retain
. An additional keyword is also provided, weak
, that would typically be used in place of assign for object types. Apple's common example of a weak
property is for delegates. I'd recommend going through the Transitioning to ARC Release Notes in addition to the Memory Management Guide a time or two as there is more nuance than can easily be covered in an SO post.
Whether I should use @property(nonatomic,copy) or @property(nonatomic,strong) for my (NSString *) attr in An object?
'copy' will cause the setter for that property to create a copy of the object, and is otherwise identical to strong. You would use this to make sure that if someone sets your property to a mutable string, then mutates the string, you still have the original value. If the string isn't mutable, Cocoa will silently optimize out the copy operation, which is nice :)
'strong' will keep the property's value alive until it's set to something else. If you want incoming mutable strings to change out from under you (not impossible, but not all that common, a thing to want), then strong would be the right thing to do. Generally strong is more useful for objects that represent something more complex than a simple "value" (i.e. not NSString, NSNumber, NSValue, etc...).
'assign' is the default (and indeed only) possible setting for an integer. Integers can't be retained or copied like objects.
Objective C - Assign, Copy, Retain
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).
Objective-C declared @property attributes (nonatomic, copy, strong, weak)
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. @property
s 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.
Objective-C Mutable property, copy retain, etc?
Use nonatomic
when you care more about performance than thread safety. Atomic properties are thread safe but slower. The default behaviour is atomic
.
Use copy
when you want a copy to be made whenever a new value is set to the property. Note that in many cases, copy
will not actually make a copy of the object, so this usually has no performance impact but can solve bugs if somebody gives you a mutable copy (eg, you have an NSString
property and somebody assigns an NSMutableString
.
Do not ever use retain
or strong
as these are only needed when ARC is turned off, and you should always have ARC turned on. strong
and retain
are the same, and this is the default behaviour with ARC enabled. Just turn ARC on and ignore these ones, except for backwards compatible code.
Sometimes, for example delegate properties, using retain
or strong
would create a memory leak. In these situtaions you need to use weak
or assign
. In general, you should use weak
, as assign
can have rare edge case bugs.
Related Topics
Determine on Iphone If User Has Enabled Push Notifications
Get the Current Scroll Position of a Swiftui Scrollview
Detecting the Call Events in Ios
How to Compare Two Uiimage Objects
Swift - How to Get the File Path Inside a Folder
How to Determine If an Annotation Is Inside of Mkpolygonview (Ios)
Setting Custom Uitableviewcells Height
Disable Uiscrollview Scrolling When Uitextfield Becomes First Responder
Adding Images or Videos to iPhone Simulator
Uiactivityviewcontroller Crashing on iOS 8 Ipads
Iphone Get a List of All Ssids Without Private Library
#Warning: C-Style For Statement Is Deprecated and Will Be Removed in a Future Version of Swift
Xcode, Where to Assign the Segue Identifier
Library Not Loaded: @Rpath/Fblpromises.Framework/Fblpromises iOS 13.3.1
How to Disable Copy Paste Option from Uitextfield Programmatically