7
votes

Comment appeler la mise en œuvre originale lors de l'écrasement d'une méthode avec une catégorie?

J'essaie de comprendre comment les choses fonctionnent vraiment. J'ai donc pensé que lorsque je voudrais écraser certaines méthodes en utilisant des catégories, je voudrais obtenir des nslogs intéressants. XXX

SUPER ET SOI ne fonctionne pas ici. Existe-t-il un moyen d'appeler la mise en œuvre originale de -Hittest: sans:? Ce que je veux, c'est un NSLOG à chaque fois -Hittest: Withevent: est appelé sur un UIView.

C'est juste à des fins d'apprentissage personnelles. Je veux voir la livraison de l'événement en action.


2 commentaires

Super ne fonctionne pas dans une catégorie car vous ne l'appelez pas sur la même classe, vous l'appelez sur le super de la classe. Donc, dans ce cas, le Super est un répondeur qui n'a pas de baisse: contrainte. Appeler Self Il en résulte une boucle infinie parce que vous prenez de l'essentiel: déporté de "soi".


Mon commentaire semble un peu hors de propos ici, mais cela a eu du sens avant que les précédents commentés ont supprimé le sien.


3 Réponses :


0
votes

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

Envoi du même message à Super devrait fonctionner dans votre méthode; Il appellera la méthode sur la superclasse comme normale (s'il y en a un).

Envoi du même message à Self créera une boucle infinie, car je suis sûr que vous avez découvert.


1 commentaires

Comme Adam l'a dit, ce n'est pas possible de cette manière, mais vous pourriez jeter un coup d'œil à la méthode Swizzling. Il y a un excellent exemple ici: Github.com/marksands/uitextviewLinkOPtions



3
votes

Ce que vous voulez faire est appelé méthode Swizzling: http://www.cocoadev.com/ Index.pl?methodswizzling


2 commentaires

Je ne suis pas sûr, mais l'article semble être un peu obsolète. Dave Delong a posté une solution qui fonctionne assez bien avec beaucoup moins de code. Merci quand même :-)


@Bugalert Tout simplement que vous êtes au courant, mon code est méthode Swizzling. L'article lié a simplement beaucoup plus d'informations à ce sujet. :)



16
votes

Vous pouvez le faire, mais n'utilisez pas une catégorie. Une catégorie remplace une méthode. (Avertissement, analogie de la voiture) Si vous avez une voiture, vous détruisez cette voiture et remplacez-la par une nouvelle voiture, pouvez-vous toujours utiliser la vieille voiture? Non, parce que c'est parti et n'existe plus. La même chose avec les catégories.

Ce que vous pourriez faire est d'utiliser l'exécution de l'objectif-C pour ajouter la méthode sous un nom différent à l'exécution (disons, " Bogushittest: sans: code>"), puis échangez le Mises en œuvre de Hittest: Sans: Code> et BOGUSHITTESTTEST: SANSEvent: code>. Ainsi, lorsque le code appelle Hittest: Sans: code>, il va exécuter le code qui a été écrit à l'origine pour Bogushittest: windevent: code>. Vous pouvez alors avoir ce code invoquer BOGUSHITTESTTEST: SANSEvent: code>, qui exécutera la mise en oeuvre d'origine. P>

de sorte que la méthode Bogus ressemblerait à: P>

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


0 commentaires