74 votes

Meilleure pratique lors de la mise en œuvre de copyWithZone:

J'essaie d'éclaircir quelques points dans ma tête concernant la mise en œuvre de copyWithZone: , quelqu'un peut-il commenter ce qui suit ...

 // 001: Crime is a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [[[self class] allocWithZone:zone] init];
    if(newCrime) {
        [newCrime setMonth:[self month]];
        [newCrime setCategory:[self category]];
        [newCrime setCoordinate:[self coordinate]];
        [newCrime setLocationName:[self locationName]];
        [newCrime setTitle:[self title]];
        [newCrime setSubtitle:[self subtitle]];
    }
    return newCrime;
}

// 002: Crime is not a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [super copyWithZone:zone];
    [newCrime setMonth:[self month]];
    [newCrime setCategory:[self category]];
    [newCrime setCoordinate:[self coordinate]];
    [newCrime setLocationName:[self locationName]];
    [newCrime setTitle:[self title]];
    [newCrime setSubtitle:[self subtitle]];
    return newCrime;
}
 

En 001:

  1. Est-il préférable d'écrire directement le nom de la classe [[Crime allocWithZone:zone] init] ou devrais-je utiliser [[[self Class] allocWithZone:zone] init] ?

  2. Puis-je utiliser [self month] pour copier les iVars ou devrais-je accéder directement aux iVars, c’est-à-dire _month ?

98voto

Tony Points 2331
  1. Vous devriez toujours utiliser [[self class] allocWithZone:zone] à assurez-vous que vous êtes la création d'une copie à l'aide de la classe appropriée. L'exemple que vous donnez aux 002 montre exactement pourquoi: les sous-classes appellera [super copyWithZone:zone] et espérer obtenir en retour une instance de la classe, et non une instance de la super-classe.

  2. - Je accéder à la ivars directement, donc je n'ai pas besoin de vous soucier des effets secondaires que je pourrais ajouter à l'accesseur de propriété (par exemple, la génération de notifications) plus tard. Gardez à l'esprit, les sous-classes sont libres de remplacer n'importe quelle méthode. Dans votre exemple, vous êtes l'envoi de deux messages supplémentaires par ivar. Je voudrais mettre en œuvre comme suit:

Code:

- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [super copyWithZone:zone];
    newCrime->_month = [_month copyWithZone:zone];
    newCrime->_category = [_category copyWithZone:zone];
    // etc...
    return newCrime;
}

Bien sûr, si vous copiez le ivars, de les retenir, ou tout simplement de les affecter devrait être le reflet de ce que les poseurs de le faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X