2009-07-16 120 views
3

这是Objective-C 2.0编程语言的一个例子。 我只是想知道,在底部的二传手,我可以使用value = [newValue retain] 而不是value = [newValue copy]关于setter在objective-c中的问题

@interface MyClass : NSObject 

{ 

    NSString *value; 

} 

@property(copy, readwrite) NSString *value; 

@end 



// assume using garbage collection 

@implementation MyClass 

@dynamic value; 



- (NSString *)value { 

    return value; 

} 



- (void)setValue:(NSString *)newValue { 

    if (newValue != value) { 

     value = [newValue copy]; 

    } 

} 

@end 

回答

7

要做的最快和最安全的事情是将@synthesize value添加到您的实现的顶部,编译器将自动生成这些方法。

复制与保留的问题取决于您可能在NSMutableString中传递的事实,这会改变它的值。如果你有一个“不可变”类型(字符串,集合,数组,字典)的setter,你需要使用copy语义。起初,这看起来可能违反直觉(为什么复制它是不可变的?),但要实现的是,你的类想要认为它是不可变的,传入的内容可能并不是不可变的。

NSMutable类通过返回它们表示的不可变版本来实现copy选择器。不可变类(NSString等)通过调用retain实现copy。这就是说,它们非常快。

您的二传手还需要在为其分配一个新值之前释放value。正确的代码是:

-(void)setValue:(NSString*)newvalue 
{ 
    if (value != newvalue) 
    { 
     [value release]; 
     value = [newvalue copy]; 
    } 
} 

如果你拥有对所有可能调用setValue:和有绝对的把握,你将不会被传递的NSMutableString,您可以使用retain类的完全控制,但它的使用copy最佳实践。

0

不,您的接口说copy。如果有人传入一个NSMutableString,你将会得到两种方法非常不同的结果。

+0

通过API,教会意味着你的`value`财产申报。两者都应该是“复制”或“保留”。 – notnoop 2009-07-16 15:19:59

+0

所以通过使用副本,我可以跳过类型检查,以避免运行时错误,这是什么想法? – derrdji 2009-07-16 15:21:09

0

这取决于。如果使用[newValue retain],另一个对象可能会更改此NSString指针的值。通常情况下,你不喜欢这种行为。

0

setter方法:

-(void)setValue:(NSString*)newvalue{ 
     if (_value != newvalue) 
     { 
      [_value release]; 
      _value = nil; 
      _value = [newvalue copy]; 

     } 
    }