NSString property: copy or retain?

Let's say I have a class called SomeClass with a string property name:

@interface SomeClass : NSObject
{
    NSString* name;
}

@property (nonatomic, retain) NSString* name;

@end

I understand that name may be assigned a NSMutableString in which case this may lead to errant behavior.

  • For strings in general, is it always a good idea to use the copy attribute instead of retain ?
  • Is a "copied" property in any way less efficient than such a "retain-ed" property?

  • For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your @property declaration. Specifying retain is something you almost never want in such a situation.

    Here's why you want to do that:

    NSMutableString *someName = [NSMutableString stringWithString:@"Chris"];
    
    Person *p = [[[Person alloc] init] autorelease];
    p.name = someName;
    
    [someName setString:@"Debajit"];
    

    The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be @"Debajit" if the property is marked retain , but @"Chris" if the property is marked copy .

    Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy . (And if you write the setter yourself instead of using @synthesize you should remember to actually use copy instead of retain in it.)


    Copy should be used for NSString. If it's Mutable, then it gets copied. If it's not, then it just gets retained. Exactly the semantics that you want in an app (let the type do what's best).


    For strings in general, is it always a good idea to use the copy attribute instead of retain?

    Yes - in general always use the copy attribute.

    This is because your NSString property can be passed an NSString instance or an NSMutableString instance , and therefore we can not really determine if the value being passed is an immutable or mutable object.

    Is a "copied" property in any way less efficient than such a "retain-ed" property?

  • If your property is being passed an NSString instance , the answer is " No " - copying is not less efficient than retain.
    (It's not less efficient because the NSString is smart enough to not actually perform a copy.)

  • If your property is passed an NSMutableString instance then the answer is " Yes " - copying is less efficient than retain.
    (It's less efficient because an actual memory allocation and copy must occur, but this is probably a desirable thing.)

  • Generally speaking a "copied" property has the potential to be less efficient - however through the use of the NSCopying protocol, it's possible to implement a class which is "just as efficient" to copy as it is to retain. NSString instances are an example of this.

  • Generally (not just for NSString), when should I use "copy" instead of "retain"?

    You should always use copy when you don't want the internal state of the property changing without warning. Even for immutable objects - properly written immutable objects will handle copy efficiently (see next section regarding immutability and NSCopying ).

    There may be performance reasons to retain objects, but it comes with a maintenance overhead - you must manage the possibility of the internal state changing outside your code. As they say - optimize last.

    But, I wrote my class to be immutable - can't I just "retain" it?

    No - use copy . If your class is really immutable then it's best practice to implement the NSCopying protocol to make your class return itself when copy is used. If you do this:

  • Other users of your class will gain the performance benefits when they use copy .
  • The copy annotation makes your own code more maintainable - the copy annotation indicates that you really don't need to worry about this object changing state elsewhere.
  • 链接地址: http://www.djcxy.com/p/53264.html

    上一篇: autorelease什么时候真的会在Cocoa Touch中导致发布?

    下一篇: NSString属性:复制或保留?