2010-11-03 4 views
14

Je suis confus quant à l'utilisation et quand. Y a-t-il une règle générale? Peut-on dans la plupart des cas être utilisé? Des règles spéciales?Quand utiliser conserver et quand utiliser copier

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

Dans ce cas, quel serait le meilleur choix?

Merci -Code

Répondre

14

Vous voudrez utiliser la copie si vous ne voulez pas que l'objet soit modifié par un autre objet.

Un bon exemple est NSString. Disons que vous avez ce code:

@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"]; 

Qu'est-ce qui se passe ici est que vous attribuez la valeur « test » à aString, mais il se modifie à l'extérieur et il devient « test2 », parce que vous RÉPARTIS la chaîne mutable . Si vous aviez défini copy, cela ne se produirait pas, car vous effectuez une copie de la chaîne mutable.

1

Avec copie, vous aurez 2 objets différents. Donc, si vous modifiez un, l'autre ne sera pas modifié.

1

La copie vous donne un objet distinct.

En général, vous devriez simplement utiliser retain, à moins que vous ne souhaitiez explicitement faire des copies d'objets. Chaque fois que vous copiez, vous devez libérer, alors gardez cela à l'esprit.

Un bon moment pour utiliser -copy est lorsque vous allez utiliser l'énumération pour ajouter ou supprimer des objets.

Prenez un tableau, par exemple. Si vous énumérez le tableau, vous ne pouvez pas ajouter ou supprimer des objets pendant l'énumération, sinon vous allez planter. Avant de commencer l'énumération, utilisez -copy pour créer une nouvelle copie du tableau, et comme vous l'énumérez, si vous devez ajouter/supprimer un objet (muter), vous pouvez le faire sur la copie. Lorsque vous avez terminé l'énumération, vous pouvez rétablir la copie dans l'original.

9

NSDate est immutable et nous n'avons pas de sous-classe mutable pour le moment. Donc, retenez est bien. La copie ne fera pas de mal non plus, et en effet je m'attends à ce que la copie revienne juste à la même instance ici (retenue une fois de plus).

La raison de l'utilisation de copie sur NSString est que vous pourriez obtenir un NSMutableString transmis à votre objet à la place qui pourrait changer directement sous vos pieds. Cela ne peut pas arriver ici.

3

Dans iOS, vous travaillez généralement avec un thread unique, il n'y a donc aucune chance que votre objet soit modifié simultanément. De plus, même si vous spécifiez copy, la propriété peut encore être modifiée en la réinitialisant.

La règle du pouce est: « utiliser retain sur iOS »

Cependant, il y a peu de situations que l'utilisation de la copie est nécessaire/conseillé:

  • vous doit copie utiliser si vous acceptez Bloque les blocs (blocs de code ajoutés avec iOS4) car les blocs doivent être copiés avant de les conserver (voir Copying blocks (ie: copying them to instance variables) in Objective-C pour plus de détails
  • si vous écrivez du code qui sera exécuté dans backgrou il est plus sûr d'utiliser (atomique, copie).
  • Vous devriez envisager d'utiliser la copie si vous voulez vous assurer que seule l'affectation à la propriété change sa valeur. (Il pourrait être utile si vous implémentez KVO)
3

La règle de base est d'utiliser copy si la classe implémente le protocole NSCopying sauf si vous avez une bonne raison de ne pas. La seule bonne raison à laquelle je peux penser est la performance. Par exemple, techniquement, vous devriez utiliser copy pour les propriétés NSMutableArray, mais comme vous pouvez l'imaginer, la copie de grandes matrices mutables coûtera cher en temps CPU et en mémoire.