2009-07-16 119 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]; 

     } 
    }