Réponses:
Comme toujours avec les types référence, il existe deux notions de «copie». Je suis sûr que vous les connaissez, mais par souci d'exhaustivité.
Vous voulez ce dernier. S'il s'agit de l'un de vos propres objets, vous devez simplement adopter le protocole NSCopying et implémenter - (id) copyWithZone: (NSZone *) zone. Vous êtes libre de faire ce que vous voulez; bien que l'idée soit de faire une vraie copie de vous-même et de la renvoyer. Vous appelez copyWithZone sur tous vos champs, pour faire une copie profonde. Un exemple simple est
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
// We'll ignore the zone for now
YourClass *another = [[YourClass alloc] init];
another.obj = [obj copyWithZone: zone];
return another;
}
autorelease
pas, ou est-ce que je manque quelque chose ici
copyWithZone:
répond à ces critères, il doit donc renvoyer un objet avec un nombre de rétention de +1.
alloc
au lieu de allocWithZone:
puisque la zone a été transmise?
allocWithZone
.
La documentation Apple dit
Une version de sous-classe de la méthode copyWithZone: doit envoyer le message à super en premier, pour incorporer son implémentation, à moins que la sous-classe ne descende directement de NSObject.
pour ajouter à la réponse existante
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
YourClass *another = [super copyWithZone:zone];
another.obj = [obj copyWithZone: zone];
return another;
}
No visible @interface for 'NSObject' declares the selector 'copyWithZone:'
. Je suppose que cela n'est nécessaire que lorsque nous héritons d'une autre classe personnalisée qui implémentecopyWithZone
Je ne connais pas la différence entre ce code et le mien, mais j'ai des problèmes avec cette solution, alors j'ai lu un peu plus et j'ai trouvé que nous devions définir l'objet avant de le renvoyer. Je veux dire quelque chose comme:
#import <Foundation/Foundation.h>
@interface YourObject : NSObject <NSCopying>
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *line;
@property (strong, nonatomic) NSMutableString *tags;
@property (strong, nonatomic) NSString *htmlSource;
@property (strong, nonatomic) NSMutableString *obj;
-(id) copyWithZone: (NSZone *) zone;
@end
@implementation YourObject
-(id) copyWithZone: (NSZone *) zone
{
YourObject *copy = [[YourObject allocWithZone: zone] init];
[copy setNombre: self.name];
[copy setLinea: self.line];
[copy setTags: self.tags];
[copy setHtmlSource: self.htmlSource];
return copy;
}
J'ai ajouté cette réponse parce que j'ai beaucoup de problèmes avec ce problème et je n'ai aucune idée de pourquoi cela se produit. Je ne connais pas la différence, mais ça marche pour moi et peut-être que ça peut aussi être utile pour les autres :)
another.obj = [obj copyWithZone: zone];
Je pense que cette ligne provoque une fuite de mémoire, car vous accédez à la obj
propriété through qui est (je suppose) déclarée comme retain
. Ainsi, le nombre de rétention sera augmenté par la propriété et copyWithZone
.
Je pense que cela devrait être:
another.obj = [[obj copyWithZone: zone] autorelease];
ou:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Il y a aussi l'utilisation de l'opérateur -> pour la copie. Par exemple:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Le raisonnement ici est que l'objet copié résultant doit refléter l'état de l'objet d'origine. Le "." l'opérateur pourrait introduire des effets secondaires car celui-ci appelle des getters qui à leur tour peuvent contenir de la logique.