Question

J'essaie de comprendre comment les choses fonctionnent vraiment. Donc, je pensais quand je remplacer certaines méthodes en utilisant les catégories, je recevrais NSLogs intéressantes.

@implementation UIView(Learning)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"-hitTest:withEvent: event=%@", event);
    return [self hitTest:point withEvent:event];
}
@end

super et l'auto ne fonctionne pas ici. Est-il possible d'appeler la mise en œuvre originale de -hitTest: withEvent :? Ce que je veux est un NSLog chaque fois -hitTest: withEvent:. Est appelée sur un UIView

Il est juste à des fins d'apprentissage personnel. Je veux voir le cas dans l'action.

Était-ce utile?

La solution

Vous pouvez le faire, mais pas en utilisant une catégorie. Une catégorie remplace une autre méthode. (Attention, l'analogie de voiture) Si vous avez une voiture, et vous détruire cette voiture et le remplacer par une nouvelle voiture, vous pouvez toujours utiliser la vieille voiture? Non, car il est parti et n'existe plus. La même chose avec les catégories.

Ce que vous pouvez faire est d'utiliser le moteur d'exécution Objective-C pour ajouter la méthode sous un autre nom à l'exécution (par exemple, « bogusHitTest:withEvent: »), puis échanger les implémentations de hitTest:withEvent: et bogusHitTest:withEvent:. De cette façon, lorsque les appels de code hitTest:withEvent:, il va exécuter le code qui a été initialement écrit pour bogusHitTest:withEvent:. Vous pouvez alors ce code Invoke bogusHitTest:withEvent:, qui exécutera la mise en œuvre originale.

Ainsi, la méthode bogus ressemblerait à ceci:

- (UIView *) bogusHitTest:(CGPoint)point withEvent:(UIEvent *)event {
  NSLog(@"executing: %@", NSStringFromSelector(_cmd));
  return [self bogusHitTest:point withEvent:event];
}

Le code pour échanger les méthodes serait quelque chose le long des lignes de:

Method bogusHitTest = class_getInstanceMethod([UIView class], @selector(bogusHitTest:withEvent:));
Method hitTest = class_getInstanceMethod([UIView class], @selector(hitTest:withEvent:));
method_exchangeImplementations(bogusHitTest, hitTest);

Autres conseils

Qu'est-ce que vous voulez faire est appelée méthode swizzling: http://www.cocoadev.com/ index.pl?MethodSwizzling

Malheureusement, non, il n'y a aucun moyen d'appeler la mise en œuvre originale d'une méthode que vous substituez. Une fois que vous implémentez dans la catégorie que vous avez éliminé la méthode originale.

L'envoi du même message à super devrait fonctionner dans votre méthode; il va appeler la méthode de la superclasse normalement (si elle existe).

L'envoi du même message à self va créer une boucle infinie, comme je suis sûr que vous avez découvert.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top