How to call the original implementation when overwriting a method with a category?

I am trying to understand how everything works. So I thought that when I rewrote some methods using categories, I would get interesting NSLogs.

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

super and i don't work here. Is there any way to call the initial implementation of -hitTest: withEvent :? I want NSLog every time -hitTest: withEvent: is called in a UIView.

This is just for personal learning purposes. I want to see an event delivery in action.

+6
ios objective-c swizzling objective-c-category method-swizzling
source share
3 answers

You can do this, but without using a category. Category replaces the method. (Warning, car analogy) If you have a car and you destroy this car and replace it with a new car, can you use an old car? No, because he left and no longer exists. Same thing with categories.

What you can do is use the Objective-C runtime to add a method with a different name at runtime (say " bogusHitTest:withEvent: "), and then change the implementations of hitTest:withEvent: and bogusHitTest:withEvent: That way, when the code calls hitTest:withEvent: it will execute the code that was originally written for bogusHitTest:withEvent: Then you can call this code bogusHitTest:withEvent: which will do the initial implementation.

Thus, the dummy method will look like this:

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

The code for replacing the methods will look like this:

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

What you want to do is called the swizzling method: http://www.cocoadev.com/index.pl?MethodSwizzling

+3
source share

Unfortunately, no, there is no way to call the initial implementation of the method that you override. After you implement it in the category, you have eliminated the original method.

Sending the same message to super should work in your method; it will call the method on the superclass as normal (if any).

Sending the same message to self will result in an infinite loop, as I'm sure you discovered.

0
source share

All Articles