NSString property: copy or retain?

前端 未结 10 979
予麋鹿
予麋鹿 2020-11-22 02:53

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

@interface SomeClass : NSObject
{
    NSString* name;
}

@p         


        
相关标签:
10条回答
  • 2020-11-22 03:16

    Surely putting 'copy' on a property declaration flies in the face of using an object-oriented environment where objects on the heap are passed by reference - one of the benefits you get here is that, when changing an object, all references to that object see the latest changes. A lot of languages supply 'ref' or similar keywords to allow value types (i.e. structures on the stack) to benefit from the same behaviour. Personally, I'd use copy sparingly, and if I felt that a property value should be protected from changes made to the object it was assigned from, I could call that object's copy method during the assignment, e.g.:

    p.name = [someName copy];
    

    Of course, when designing the object that contains that property, only you will know whether the design benefits from a pattern where assignments take copies - Cocoawithlove.com has the following to say:

    "You should use a copy accessor when the setter parameter may be mutable but you can't have the internal state of a property changing without warning" - so the judgement as to whether you can stand the value to change unexpectedly is all your own. Imagine this scenario:

    //person object has details of an individual you're assigning to a contact list.
    
    Contact *contact = [[[Contact alloc] init] autorelease];
    contact.name = person.name;
    
    //person changes name
    [[person name] setString:@"new name"];
    //now both person.name and contact.name are in sync.
    

    In this case, without using copy, our contact object takes the new value automatically; if we did use it, though, we'd have to manually make sure that changes were detected and synced. In this case, retain semantics might be desirable; in another, copy might be more appropriate.

    0 讨论(0)
  • 2020-11-22 03:16
    @interface TTItem : NSObject    
    @property (nonatomic, copy) NSString *name;
    @end
    
    {
        TTItem *item = [[TTItem alloc] init];    
        NSString *test1 = [NSString stringWithFormat:@"%d / %@", 1, @"Go go go"];  
        item.name = test1;  
        NSLog(@"-item.name: point = %p, content = %@; test1 = %p", item.name, item.name, test1);  
        test1 = [NSString stringWithFormat:@"%d / %@", 2, @"Back back back"];  
        NSLog(@"+item.name: point = %p, content = %@, test1 = %p", item.name, item.name, test1);
    }
    
    Log:  
        -item.name: point = 0x9a805a0, content = 1 / Go go go; test1 = 0x9a805a0  
        +item.name: point = 0x9a805a0, content = 1 / Go go go, test1 = 0x9a84660
    
    0 讨论(0)
  • Since name is a (immutable) NSString, copy or retain makes no difference if you set another NSString to name. In another word, copy behaves just like retain, increasing the reference count by one. I think that is an automatic optimization for immutable classes, since they are immutable and of no need to be cloned. But when a NSMutalbeString mstr is set to name, the content of mstr will be copied for the sake of correctness.

    0 讨论(0)
  • 2020-11-22 03:21

    If the string is very large then copy will affect performance and two copies of the large string will use more memory.

    0 讨论(0)
提交回复
热议问题