如何在覆盖带有类别的方法时调用原始实现? [英] How to call original implementation when overwriting a method with a category?
问题描述
我试着弄清楚事情是如何运作的。所以我想当我使用类别覆盖某些方法时,我会得到有趣的NSLog。
I try to figure out how things really work. So I thought when I would overwrite certain 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
超级和自我在这里不起作用。有没有办法调用-hitTest的原始实现:withEvent:?我想要的是NSLog每次-hitTest:withEvent:在UIView上调用。
super and self don't work here. Is there a way to call the original implementation of -hitTest:withEvent:? What I want is an NSLog every time -hitTest:withEvent: is called on an UIView.
它仅用于个人学习目的。我希望看到事件交付的实际效果。
It's just for personal learning purposes. I want to see the event delivery in action.
推荐答案
您可以这样做,但不能使用类别。类别替换方法。 (警告,汽车比喻)如果你有一辆汽车,然后你摧毁那辆汽车并换上一辆新车,你还能使用旧车吗?不,因为它消失了,不再存在了。与类别相同。
You can do it, but not using a category. A category replaces a method. (Warning, car analogy) If you have a car, and you destroy that car and replace it with a new car, can you still use the old car? No, because it is gone and does not exist anymore. The same with categories.
您可以做的是使用Objective-C运行时在运行时以不同的名称添加方法(例如, bogusHitTest:withEvent:
),然后交换 hitTest的实现:withEvent:
和 bogusHitTest:withEvent:
。这样当代码调用 hitTest:withEvent:
时,它将执行最初为 bogusHitTest编写的代码:withEvent:
。然后,您可以让代码调用 bogusHitTest:withEvent:
,这将执行原始实现。
What you could do is use the Objective-C runtime to add the method under a different name at runtime (say, "bogusHitTest:withEvent:
"), then swap the implementations of hitTest:withEvent:
and bogusHitTest:withEvent:
. That way when the code calls hitTest:withEvent:
, it's going to execute the code that was originally written for bogusHitTest:withEvent:
. You can then have that code invoke bogusHitTest:withEvent:
, which will execute the original implementation.
所以伪造方法如下:
- (UIView *) bogusHitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"executing: %@", NSStringFromSelector(_cmd));
return [self bogusHitTest:point withEvent:event];
}
交换方法的代码将是:
Method bogusHitTest = class_getInstanceMethod([UIView class], @selector(bogusHitTest:withEvent:));
Method hitTest = class_getInstanceMethod([UIView class], @selector(hitTest:withEvent:));
method_exchangeImplementations(bogusHitTest, hitTest);
这篇关于如何在覆盖带有类别的方法时调用原始实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!