当用类别覆盖方法时,如何调用原始实现?
-
28-09-2019 - |
题
我试图弄清楚事情的真正工作方式。因此,我认为当我使用类别覆盖某些方法时,我会得到有趣的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上被调用。
这只是出于个人学习目的。我想看到事件的交付。
解决方案
您可以做到,但不能使用类别。一个类别替代方法。 (警告,类比)如果您有汽车,并且销毁了汽车并用新车代替它,您仍然可以使用旧车吗?不,因为它消失了,不再存在。类别相同。
您可以做的是使用Objective-C运行时间在运行时添加其他名称下的方法(例如,”bogusHitTest:withEvent:
”),然后交换 hitTest:withEvent:
和 bogusHitTest:withEvent:
. 。这样当代码调用 hitTest:withEvent:
, ,它将执行最初编写的代码 bogusHitTest:withEvent:
. 。然后您可以将代码调用 bogusHitTest:withEvent:
, ,将执行原始实施。
因此,虚假方法看起来像:
- (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);
其他提示
您要做的就是称为方法: http://www.cocoadev.com/index.pl?methodswizzling
不幸的是,不,没有办法调用您覆盖方法的原始实现。一旦在类别中实现它,您就消除了原始方法。
将相同的消息发送给 super
应该用您的方法工作;它将在超类上称呼该方法为正常(如果有)。
将相同的消息发送给 self
正如我确定您发现的那样,将创建一个无限的循环。
不隶属于 StackOverflow