2012-07-05 1 views
1

J'utilise des catégories avec des données de base. Certains des tutoriels que j'ai lus et des conférences que j'ai écoutées disent que les catégories sont souvent considérées comme une «mauvaise» pratique. Mais parce que Objective-C est si dynamique, il semble parfaitement correct de définir des méthodes ailleurs, notamment parce que seules les propriétés publiques d'une classe peuvent être utilisées. Quels sont les pièges que je devrais surveiller lorsque j'utilise des catégories? Ou y a-t-il une raison pour que les catégories soient en fait une mauvaise pratique? La raison pour laquelle je les utilise avec Core Data est que je n'ai pas la possibilité de réécrire mes méthodes add-on chaque fois que je régénère les sous-classes.Quand les catégories sont-elles mauvaises/dangereuses?

+1

La seule fois où j'ai vu des commentaires anti-catégorie est quand ils sont utilisés dans le but de redéfinir les méthodes existantes. Si elles sont mauvaises dans le cas général, je pense que cela va surprendre un grand nombre d'ingénieurs logiciels d'Apple, compte tenu de la fréquence à laquelle ils sont utilisés dans le SDK et dans l'exemple de code. –

Répondre

6

Le seul «danger» auquel je peux penser est lorsque vous les utilisez pour remplacer les méthodes de la classe d'origine plutôt que de sous-classer. Ce faisant, vous perdez la possibilité d'accéder à l'implémentation d'origine, qui, étant donné qu'elle est généralement une méthode privée que vous remplacez, peut avoir des effets imprévus.

L'utilisation de catégories pour ajouter extra méthodes à n'importe quel objet d'une classe particulière est grande, et précisément ce qu'ils sont. Les utiliser pour les données de base, comme vous le faites, est bien car cela vous permet de changer de modèle et de régénérer l'objet "vanilla" sans détruire le code supplémentaire.

Astuce du chapeau à @CodaFi pour ce morceau de documentation de la pomme:

Bien que le langage Objective-C vous permet actuellement d'utiliser une catégorie pour remplacer les méthodes de la classe, ou même hérite des méthodes déclarées dans l'interface de classe, vous êtes fortement découragé de le faire. Une catégorie ne remplace pas une sous-classe. 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. Il existe plusieurs inconvénients importants à l'utilisation d'une catégorie pour substituer des méthodes:

Lorsqu'une catégorie remplace une méthode héritée, la méthode de la catégorie peut, comme d'habitude, appeler l'implémentation héritée via un message à super. Toutefois, si une catégorie remplace une méthode qui existe dans la classe de la catégorie, il est impossible d'invoquer 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 la plupart des classes Cocoa sont implémentées en utilisant des 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 donc quelle implémentation a la priorité n'est pas définie.

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

+0

Merci pour la réponse, la partie sur laquelle la mise en œuvre a la priorité est particulièrement intéressante. – Dustin

Questions connexes