2010-11-03 4 views
14

Ich bin verwirrt darüber, was zu verwenden und wann. Gibt es eine Faustregel? Kann in den meisten Fällen einer von beiden verwendet werden? Irgendwelche Sonderregeln?Wann zu verwenden behalten und wann zu kopieren

@property (nonatomic, retain) NSDate *theDateFromPicker; 
@property (nonatomic, copy) NSDate *theDateFromPicker; 

In diesem Fall, was wäre die beste Wahl?

Dank -Code

Antwort

14

Sie möchten die Kopie verwenden, wenn Sie nicht möchten, dass das Objekt von einem anderen Objekt geändert wird.

Ein gutes Beispiel ist NSString. Angenommen, Sie haben diesen Code haben:

@property (nonatomic, retain) NSString *aString; 

// in some other class 

NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"test"]; 
theObject.aString = mutableString; // theObject retains the mutable string 

[mutableString setString:@"test2"]; 

Was hier passiert, ist, dass Sie den Wert „Test“ zu aString, weisen aber dann wird es extern geändert, und es wird „test2“, weil Sie die veränderbare Zeichenfolge beibehalten . Wenn Sie copy festgelegt hätten, würde dies nicht passieren, weil Sie eine Kopie der veränderbaren Zeichenfolge erstellen.

1

Mit kopieren Sie zwei verschiedene Objekte haben werden. Wenn Sie also einen ändern, wird der andere nicht geändert.

1

Kopieren gibt Ihnen ein separates Objekt.

Im Allgemeinen sollten Sie nur retain verwenden, es sei denn, Sie möchten explizit Kopien von Objekten erstellen. Jedes Mal, wenn du kopierst, musst du loslassen, also behalte das im Hinterkopf.

Eine gute Zeit zu verwenden -copy ist, wenn Sie Enumeration verwenden, um Objekte hinzuzufügen oder zu entfernen.

Nehmen Sie ein Array zum Beispiel. Wenn Sie das Array aufzählen, können Sie ihm während der Aufzählung keine Objekte hinzufügen oder entfernen oder Sie stürzen ab. Bevor Sie die Enumeration starten, verwenden Sie -copy, um eine neue Kopie des Arrays zu erstellen, und wenn Sie ein Objekt hinzufügen/entfernen (mutieren), müssen Sie dies beim Kopieren tun.

Wenn Sie mit der Aufzählung fertig sind, können Sie die Kopie auf das Original zurücksetzen.

9

NSDate ist unveränderlich und wir haben keine veränderbare Unterklasse zu diesem Zeitpunkt. Also behalten ist in Ordnung. Kopieren tut auch nicht weh, und in der Tat erwarte ich, dass die Kopie genau die gleiche Instanz hier zurückgibt (noch einmal beibehalten).

Der Grund für die Verwendung Kopie bei NSString ist, dass Sie möglicherweise eine NSMutableString an Ihr Objekt übergeben, die möglicherweise direkt unter Ihren Füßen ändern kann. Dies kann hier nicht passieren.

3

In iOS arbeiten Sie normalerweise mit einem einzelnen Thread, so dass es keine Chance gibt, dass Ihr Objekt gleichzeitig geändert wird. Darüber hinaus, auch wenn Sie copy angeben, kann die Eigenschaft noch geändert werden, indem Sie sie einfach erneut festlegen.

Die Regel des Daumens ist: „retain auf iOS verwenden“

Allerdings gibt es einige Situationen, dass die Verwendung von Kopie erforderlich ist/empfohlen:

  • Sie Muss Gebrauch kopieren, wenn Sie akzeptieren Blöcke (Blöcke mit Code, die mit iOS4 hinzugefügt wurden), da die Blöcke vor der Speicherung in den Heap kopiert werden müssen (siehe Copying blocks (ie: copying them to instance variables) in Objective-C für weitere Details
  • wenn Sie Code schreiben, der in TERGRU ausgeführt wird nd es ist sicherer zu verwenden (atomare, Kopie).
  • sollten Sie die Verwendung von copy in Erwägung ziehen, wenn Sie sicherstellen möchten, dass nur die Zuweisung an die Eigenschaft den Wert ändert. (Es könnte nützlich sein, wenn Sie KVO implementieren)
3

Die Faustregel copy verwenden, wenn die Klasse implementiert das NSCopying Protokoll, es sei denn Sie haben guten Grund, nicht zu. Der einzige gute Grund, an den ich denken kann, ist Leistung. Zum Beispiel sollten Sie technisch copy für NSMutableArray Eigenschaften verwenden, aber wie Sie sich vorstellen können, wird das Kopieren großer veränderbarer Arrays in CPU-Zeit und Speicher teuer.

Verwandte Themen