2010-07-11 14 views
12

Je connais un couple de règles concernant les catégories Objective-C:Que se passe-t-il si deux catégories ObjC remplacent la même méthode?

  1. méthodes de catégorie ne devrait pas surcharger les méthodes existantes (classe ou d'instance)
  2. Deux différentes catégories d'application de la même méthode pour la même classe se traduira par un comportement non défini

Je voudrais savoir ce qui se passe quand j'Override un de mes propres méthodes de catégorie en t la même catégorie. Par exemple:

@interface NSView (MyExtensions) 
- (void)foo; // NSView category implementation 
@end 

@interface MyClass : NSView 
{ } 
@end 

@interface MyClass (MyExtensions) 
- (void)foo; // MyClass category implementation 
@end 

Avec ces interfaces définies, quelle méthode sera exécutée lorsque j'exécuter le code suivant?

MyClass * instance = [[MyClass alloc] initWith...]; 
[instance foo]; 
[instance release]; 

Note: Avec mon compilateur, la mise en œuvre de MyClass a la priorité, mais je ne suis pas sûr si cela est garanti de se produire, ou tout simplement une saveur spécifique du comportement non défini.

Répondre

12

Chaque méthode de chaque classe a une implémentation. Une catégorie ajoute ou remplace une méthode pour une classe spécifique. Cela signifie que le comportement que vous voyez, où MyClass a un foo et NSView a un autre foo, est bien défini. Toute instance de MyClass aura un foo différent de toute instance de NSView qui n'est pas une classe MyClass, tout comme si foo avait été défini dans l'implémentation principale et non une catégorie. Vous devriez même pouvoir appeler [super foo] de MyClass pour accéder au foo défini pour NSView.

+3

Est-il correct de surcharger dans la méthode Catégorie déclarée et implémentée dans Catégorie de super classe? – BergP

32

Pour étendre sur la réponse de drawnonward:

Il est question de la hiérarchie. Les catégories sont vraiment juste un moyen d'organiser les fichiers source. Une fois compilées, toutes les méthodes d'une classe, y compris celles définies dans une catégorie, se retrouvent dans le même fichier.

Tout ce que vous pourriez faire dans une interface de classe régulière, vous pouvez faire dans une catégorie et tout ce que vous ne devriez pas faire dans une interface de classe régulière, vous ne devriez pas faire dans une catégorie.

Alors:

méthodes de catégorie ne devrait pas passer outre les méthodes existantes (classe ou d'instance)

Vous pouvez utiliser des méthodes définies dans l'interface de classe régulière pour remplacer hérité méthodes afin que vous puissiez remplacer les méthodes héritées dans une catégorie. Cependant, vous ne devriez jamais essayer d'avoir deux définitions de méthodes identiques dans la même interface ordinaire, vous ne devriez donc jamais avoir une méthode dans une catégorie qui a le même nom qu'une méthode dans l'interface ordinaire ou dans une autre catégorie sur le même classe. Étant donné que toutes les définitions de méthode se retrouvent dans le même fichier compilé, elles entreraient inévitablement en collision.

Deux différentes catégories d'application les mêmes résultats de la méthode de comportement non défini

Cela devrait être réécrite pour dire « Deux différentes catégories d'application de la même méthode pour la même classe résultats dans undefined comportement." Encore une fois, parce que toutes les méthodes d'une classe se retrouvent dans le même fichier, avoir deux méthodes dans la même classe causerait évidemment de l'étrangeté.

Vous pouvez utiliser des catégories pour fournir des méthodes qui remplacent les méthodes de super-classe car une classe et sa super-classe sont deux classes distinctes. Si vous êtes déjà confus quant à savoir si une catégorie posera problème, demandez-vous ceci: "Les méthodes de la catégorie fonctionneraient-elles si je les copiais et les collais dans les fichiers de classe .h/.m?" Si la réponse est "oui" alors vous êtes en clair. Si "non", alors vous avez des problèmes.

+2

+1 Merci. C'est un très bon moyen de le décrire. J'ai également modifié le libellé de la règle 2 pour qu'il corresponde au vôtre. –