NSString属性:复制或保留?

假设我有一个名为SomeClass的类,它具有一个string属性名称:

@interface SomeClass : NSObject
{
    NSString* name;
}

@property (nonatomic, retain) NSString* name;

@end

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

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

  • 对于类型为符合NSCopying协议的不可变值类的属性,几乎总是应该在@property声明中指定copy 。 指定retain是你在这种情况下几乎不需要的东西。

    这就是为什么你想这样做:

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

    Person.name属性的当前值将根据属性是否声明为retaincopy而有所不同 - 如果属性标记为retain ,则为@"Debajit"如果属性标记为copy则为@"Chris"

    由于在几乎所有情况下,您都希望防止对象背后的对象属性发生变化,因此应该将代表它们的属性标记为copy 。 (如果你自己编写setter而不是使用@synthesize你应该记得实际使用copy而不是retain 。)


    复制应该用于NSString。 如果它是可变的,那么它会被复制。 如果不是,那么它会被保留下来。 准确地说你想在应用中使用的语义(让类型做最好的)。


    对于一般的字符串,使用copy属性而不是retain是个好主意吗?

    是的 - 一般总是使用复制属性。

    这是因为你的NSString属性可以传递一个NSString实例或一个NSMutableString实例 ,因此我们不能真正确定被传递的值是不可变的还是可变的对象。

    是否“复制”的财产比这样的“保留财产”效率低?

  • 如果您的属性正在传递NSString实例 ,则答案为“ ” - 复制的效率并不低于保留。
    (它的效率并不低,因为NSString足够聪明,不会真正执行副本。)

  • 如果你的属性传递了一个NSMutableString实例,那么答案是“ ” - 复制效率低于保留。
    (效率不高,因为实际的内存分配和复制必须发生,但这可能是一个理想的事情。)

  • 一般来说,“复制”属性可能效率较低 - 但通过使用NSCopying协议,可以实现一个“同样高效”的类来复制和保留。 NSString实例就是这样的一个例子。

  • 一般来说(不只是对于NSString),什么时候应该使用“复制”而不是“保留”?

    如果您不希望在没有警告的情况下更改内部状态,则应始终使用copy 。 即使对于不可变的对象 - 正确编写的不可变对象将有效地处理拷贝(参见下一节关于不变性和NSCopying )。

    retain对象可能有性能方面的原因,但它带来了维护开销 - 您必须管理内部状态在代码之外更改的可能性。 正如他们所说 - 最后优化。

    但是,我写我的课是不变的 - 我不能“保留”它吗?

    不使用copy 。 如果你的类真的是不可变的,那么最好的做法是实现NSCopying协议,使你的类在使用copy时自动返回。 如果你这样做:

  • 其他用户在使用copy时将获得性能优势。
  • copy注释使您自己的代码更易于维护 - copy注释表明您确实无需担心其他位置的此对象更改状态。
  • 链接地址: http://www.djcxy.com/p/53263.html

    上一篇: NSString property: copy or retain?

    下一篇: Equivalent of typedef in C#