Remplacement de méthodes utilisant des catégories dans Objective-C

87

Puis-je utiliser une catégorie de classe pour remplacer une méthode qui est déjà implémentée à l'aide d'une catégorie? Comme ça:

1) Méthode originale

-(BOOL) method {
  return true;
}

2) Méthode remplacée

-(BOOL) method {
  NSLog(@"error?"); 
  return true; 
}

Cela fonctionnera-t-il ou est-ce illégal?

retix
la source

Réponses:

145

À partir de la documentation Apple :

Bien que le langage Objective-C vous permette actuellement d'utiliser une catégorie pour remplacer les méthodes dont la classe hérite, ou même les méthodes déclarées dans l'interface de classe, vous êtes fortement déconseillé de le faire . Une catégorie ne remplace pas une sous-classe. L'utilisation d'une catégorie pour remplacer des méthodes présente plusieurs lacunes importantes:

  • Lorsqu'une catégorie remplace une méthode héritée, la méthode de la catégorie peut, comme d'habitude, invoquer l'implémentation héritée via un message à super. Cependant, si une catégorie remplace une méthode qui existe dans la classe de la catégorie, il n'y a aucun moyen d'appeler l'implémentation d'origine .

  • Une catégorie ne peut pas remplacer de manière fiable les méthodes déclarées dans une autre catégorie de la même classe.

    Ce problème est particulièrement important car de nombreuses classes Cocoa sont implémentées à l'aide de catégories. Une méthode définie par le framework que vous essayez de remplacer peut elle-même avoir été implémentée dans une catégorie, et l'implémentation qui a la priorité n'est donc pas définie.

  • La présence même de certaines méthodes de catégorie peut entraîner des changements de comportement dans tous les frameworks. Par exemple, si vous remplacez la windowWillClose:méthode de délégué dans une catégorie sur NSObject, tous les délégués de fenêtre de votre programme répondent alors en utilisant la méthode de catégorie; le comportement de toutes vos instances de NSWindow peut changer. Les catégories que vous ajoutez à une classe de framework peuvent provoquer des changements de comportement mystérieux et entraîner des plantages.

Benoît
la source
Merci mais je le sais déjà. Je me demande simplement que mon cas soit légal ou non. Mon cas est un peu différent des documents. :)
retix
Pourquoi est-ce différent? La doc dit que c'est légal SI la méthode originale n'est pas dans une catégorie, mais fortement déconseillée. Alors tu peux le faire ...
Benoît
1
Merci pour ton conseil. Je suis pauvre dans cette langue. J'ai reçu de nouvelles informations de votre part.
retix
1
Est-il correct de remplacer dans la méthode Category déclarée et implémentée dans Category of super class?
BergP
2
Le lien est rompu, est-ce la nouvelle version? developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
RndmTsk
9

L'ancien lien de documentation est mort; le meilleur remplacement que j'ai pu trouver était ici: Apple Docs :

Éviter les conflits de nom de méthode de catégorie

Étant donné que les méthodes déclarées dans une catégorie sont ajoutées à une classe existante, vous devez faire très attention aux noms de méthode.

Si le nom d'une méthode déclarée dans une catégorie est le même qu'une méthode dans la classe d'origine, ou une méthode dans une autre catégorie sur la même classe (ou même une superclasse), le comportement n'est pas défini quant à l'implémentation de méthode utilisée à Durée. Cela risque moins de poser problème si vous utilisez des catégories avec vos propres classes, mais cela peut poser des problèmes lors de l'utilisation de catégories pour ajouter des méthodes aux classes Cocoa ou Cocoa Touch standard.

C'est Apple qui utilise une touche plus légère, mais le point principal est le même: vous invitez au désastre, car le comportement imprévisible est silencieux.

AmitaiB
la source
2

Il est important de noter qu'une catégorie peut également être utilisée pour remplacer des méthodes existantes dans la classe de base (par exemple, la méthode d'entraînement de la classe Car), mais vous ne devriez jamais faire cela. Le problème est que les catégories sont une structure organisationnelle plate. Si vous remplacez une méthode existante dans Car + Maintenance.m et que vous décidez ensuite de modifier à nouveau son comportement avec une autre catégorie, Objective-C n'a aucun moyen de savoir quelle implémentation utiliser. Le sous-classement est presque toujours une meilleure option dans une telle situation.

À partir de ce didacticiel, http://rypress.com/tutorials/objective-c/categories

Vinuta
la source