2009-07-16 13 views
3

Dies ist ein Beispiel aus der Objective-C 2.0 Programmiersprache. Ich habe mich nur gefragt, in der Setter an der Unterseite, kann ich value = [newValue retain] anstelle von value = [newValue copy] verwenden?Eine Frage über Setter in 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 

Antwort

7

Am schnellsten und sichersten wäre es, @synthesize value an den Anfang Ihrer Implementierung hinzuzufügen, und der Compiler wird diese Methoden automatisch generieren.

Das Problem von Kopie und beibehalten hängt von der Tatsache ab, dass Sie möglicherweise in einem NSMutableString übergeben werden, der seinen Wert ändern würde. Wenn Sie einen Setter für einen 'unveränderlichen' Typ (String, Set, Array, Dictionary) haben, müssen Sie die Semantik copy verwenden. Das mag zunächst kontraintuitiv erscheinen (warum eine Kopie machen, wenn es unveränderlich ist?), Aber die zu realisierende Sache ist, dass Ihre Klasse davon ausgehen will, dass sie unveränderlich ist, und was hineingegeben wird, ist möglicherweise nicht unveränderlich.

NSMutable-Klassen implementieren den copy-Selektor, indem sie eine unveränderbare Version dessen, was sie darstellen, zurückgeben. Die unveränderlichen Klassen (NSString, usw.) implementieren copy mit einem retain Aufruf. Das heißt, sie sind sehr schnell.

Ihr Setter muss auch value freigeben, bevor er einen neuen Wert zugewiesen bekommt. Der richtige Code ist:

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

Wenn Sie alle vollständige Kontrolle über die Klassen, die setValue: und sind absolut sicher, nennen Sie nicht in NSMutableString vorbei, können Sie retain verwenden, aber es ist am besten Praktiken copy zu verwenden .

+0

ist es eine gute Idee, immer kopieren zu verwenden? kann ich auch @property (behalten, kopieren, lesen) NSString * Wert, und was wäre der Effekt? danke – derrdji

+0

Das würde nicht kompilieren. Es ist eine gute Idee, die Kopie zu verwenden, wenn Sie erwarten, dass das Element durch die Sichtbarkeit Ihrer Klasse unveränderbar ist. Wenn Sie eine Eigenschaft für etwas haben, das keinen Wert darstellt (z. B. eine UI-Ausgangseigenschaft), verwenden Sie retain. – Jason

0

Nein, Ihre Schnittstelle sagt copy. Wenn jemand einen NSMutableString übergibt, erhalten Sie sehr unterschiedliche Ergebnisse von den beiden Methoden.

+0

von API, die Kirche bedeutet, dass Ihre Erklärung der 'value' Eigenschaft. Entweder beide sollten "kopieren" oder "behalten" sein. – notnoop

+0

so mit Kopie kann ich die Typüberprüfung überspringen, um Laufzeitfehler zu vermeiden, ist das die Idee? – derrdji

0

Kommt drauf an. Wenn Sie [newValue retain] verwenden, kann ein anderes Objekt den Wert dieses NSString Zeigers ändern. Normalerweise möchten Sie dieses Verhalten nicht haben.

0

Setter-Methode:

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

     } 
    }