When to use retain and when to use copy
I'm confused about which to use and when. Is there a rule of thumb? Can in most cases either of them be used? Any special rules?
@property (nonatomic, retain) NSDate *theDateFromPicker;
@property (nonatomic, co开发者_运维知识库py) NSDate *theDateFromPicker;
In this case which would be the best choice?
Thanks -Code
You'll want to use copy when you don't want the possibility that the object gets modified by another object.
A good example is NSString
. Let's say you have this code:
@property (nonatomic, retain) NSString *aString;
// in some other class
NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"test"];
theObject.aString = mutableString; // theObject retains the mutable string
[mutableString setString:@"test2"];
What happens here is that you assign the value "test" to aString
, but then it gets modified externally and it becomes "test2", because you retained the mutable string. If you had set copy
, this wouldn't happen, because you are making a copy of the mutable string.
NSDate is immutable and we don't have a mutable subclass at this time. So retain is fine. Copy won't hurt either, and indeed I expect copy to just hand back the very same instance here (retained once more).
The reason for using copy at NSString is that you might get a NSMutableString passed to your object instead which might change right under your feet. This cannot happen here.
In iOS, you'll usually work with single thread so there is no chance that your object gets modified concurrently.
Moreover even if you specify copy
the property can still be modified by just setting it again.
The rule of the thumb is: "use retain
on iOS"
However there are few situations that using copy is required/advised:
- you must use copy if you accept Blocks (blocks of code added with iOS4) as the blocks need to be copied to heap before retaining (see Copying blocks (ie: copying them to instance variables) in Objective-C for more details
- if you writing code that will be executed in background it is safer to use (atomic, copy).
- you should consider using copy if you want to make sure that only assigning to the property changes it value. (it could be useful if you implement KVO)
The rule of thumb is use copy
if the class implements the NSCopying
protocol unless you have good reason not to. The only good reason I can think of is performance. For instance, technically you should use copy
for NSMutableArray
properties, but as you can imagine, copying large mutable arrays will get expensive in CPU time and memory.
With copy you'll have 2 different objects. So if you modify one, the other won't be modified.
Copy gives you a separate object.
In general, you should just be using retain, unless you explicitly want to make copies of objects. Each time you copy you have to release, so keep that in mind.
A good time to use -copy is when you're going to be using enumeration to add or remove objects.
Take an array, for instance. If you are enumerating the array, you can't add or remove objects to it during the enumeration, or you will crash. Before starting enumeration, use -copy to create a new copy of the array, and as you're enumerating, if you need to add/remove an object (mutate), you can do so on the copy.
When you're finished with the enumeration you can set the copy back to the original.
精彩评论