假设我有一个名为SomeClass的类,它有一个字符串属性名:

@interface SomeClass : NSObject
{
    NSString* name;
}

@property (nonatomic, retain) NSString* name;

@end

我知道,名字可以被分配一个NSMutableString在这种情况下,这可能会导致错误的行为。

对于一般的字符串,使用copy属性而不是retain属性总是一个好主意吗? “复制”的属性是否比“保留”的属性效率低?


当前回答

Copy应该用于NSString。如果它是可变的,那么它就会被复制。如果不是,那么它就会被保留。正是你在应用程序中想要的语义(让类型发挥最好的作用)。

其他回答

Copy应该用于NSString。如果它是可变的,那么它就会被复制。如果不是,那么它就会被保留。正是你在应用程序中想要的语义(让类型发挥最好的作用)。

我试着遵循这个简单的规则:

当我将对象赋值给我的属性时,我是否想保留对象在时间点上的值?使用复制。 我是否想保留这个对象而不关心它当前的内部值或将来的内部值?使用strong(保留)。

举例说明:我是想坚持“丽莎·米勒”这个名字(复制)还是我想坚持丽莎·米勒这个人(坚强)?她的名字以后可能会改成“丽莎·史密斯”,但她还是同一个人。

如果字符串非常大,那么复制将影响性能,两个大字符串的副本将使用更多的内存。

@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

你应该一直使用copy来声明NSString属性

@property (nonatomic, copy) NSString* name;

你应该阅读这些信息,以了解它是否返回不可变字符串(以防传递可变字符串)或返回保留字符串(以防传递不可变字符串)

NSCopying协议参考

实现NSCopying通过保留原始的而不是创建一个 类及其内容不可变时的新副本

值对象

对于我们的不可变版本,我们可以这样做:

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}