Remplacer une méthode via la catégorie ObjC et appeler l’implémentation par défaut?

Lorsque vous utilisez des catégories, vous pouvez remplacer les méthodes d’implémentation par vos propres méthodes, comme ceci:

// Base Class @interface ClassA : NSObject - (NSSsortingng *) myMethod; @end @implementation ClassA - (NSSsortingng*) myMethod { return @"A"; } @end //Category @interface ClassA (CategoryB) - (NSSsortingng *) myMethod; @end @implementation ClassA (CategoryB) - (NSSsortingng*) myMethod { return @"B"; } @end 

L’appel de la méthode “myMethod” après l’inclusion de la catégorie est le résultat du résultat “B”.

Quel est le moyen le plus simple d’implémenter Category de myMethod pour appeler la classe A myMethod d’origine? Autant que je puisse le comprendre, vous devrez utiliser les appels de bas niveau pour obtenir le crochet de la méthode originale pour la classe A et l’appeler, mais il semblerait qu’il y ait un moyen syntaxiquement plus facile de le faire.

Si vous voulez un moyen pirate de le faire, vous pouvez toujours utiliser la méthode swizzling (insérer ici des clauses de non-responsabilité standard). Il vous permettra de stocker les différentes méthodes en tant que sélecteurs nommés arbitrairement, puis de les échanger à runtime comme vous en avez besoin.

De la liste comp.lang.objective-C FAQ : ” Et si plusieurs catégories implémentaient la même méthode? Alors la structure de l’Univers telle que nous la connaissons cesse d’exister. En fait, ce n’est pas tout à fait vrai, mais certains problèmes seront certainement causés. Lorsqu’une catégorie implémente une méthode qui est déjà apparue dans une classe (que ce soit via une autre catégorie, ou la primitive @implementation de la classe), la définition de cette catégorie remplace la définition précédemment présente. Code C. Notez que si deux catégories remplacent la même méthode, la dernière option utilisée est “gagnante”, ce qui peut être impossible à prédire avant le lancement du code. ”

De developer.apple.com : “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 existait déjà dans la catégorie class, il n’y a aucun moyen d’invoquer l’implémentation d’origine ”

Consultez mon article sur une solution disponible sur la bibliothèque des développeurs Mac: http://codeshaker.blogspot.com/2012/01/calling-original-overridden-method-from.html

Fondamentalement, c’est la même chose que la méthode Swizzling ci-dessus avec un bref exemple:

 #import 

 @implementation Test (Logging)

 - (NSUInteger) logLength {
     NSUInteger length = [self logLength];
     NSLog (@ "Journalisation:% d", longueur);
     longueur de retour;
 }

 + (vide) charge {
     method_exchangeImplementations (class_getInstanceMethod (self, @selector (length)), class_getInstanceMethod (self, @selector (logLength)));
 }

 @fin

Avec les méthodes swizzling “helper” incluses dans ConciseKit , vous appelez en réalité l’implémentation par défaut… assez bizarrement .. en appelant votre implémentation SWIZZLED.

Vous l’avez configuré dans + (void) load , appelant + (BOOL)swizzleMethod:(SEL)originalSelector with:(SEL)anotherSelector in:(Class)klass; , c’est à dire

 [$ swizzleMethod:@selector(oldTired:) with:@selector(swizzledHotness:) in:self.class]; 

et puis dans la méthode swizzled .. supposons que ça retourne -(id) .. vous pouvez faire votre mal, ou peu importe la raison pour laquelle vous tourbillonnez en premier lieu… et puis, au lieu de retourner un object, ou selfself . .

 return [self swizzledHotness:yourSwizzledMethodsArgument]; 

Comme expliqué ici…

Dans cette méthode, il semble que nous appelions à nouveau la même méthode, provoquant une récursivité sans fin. Mais au moment où cette ligne est atteinte, les deux méthodes ont été échangées. Donc, quand nous appelons swizzled_synchronize, nous appelons en fait la méthode originale.

Cela semble étrange, mais ça marche. Cela vous permet d’append des embellissements sans fin aux méthodes existantes, et d’appeler encore “super” (en fait, vous-même) et de profiter des avantages de la méthode originale, même sans access à la source d’origine.