如何在覆盖某个类别的方法时调用原始实现?
我试图弄清楚事情是如何工作的。 所以我想,当我将覆盖某些方法使用类别,我会得到有趣的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:
然后你可以让代码调用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);
你想要做的就是调用方法swizzling: http : //www.cocoadev.com/index.pl? MethodSwizzling
不幸的是,没有办法调用你重写的方法的原始实现。 一旦你在类别中实现它,你已经消除了原来的方法。
发送同样的消息到super
应该在你的方法工作; 它将正常调用超类的方法(如果有的话)。
发送相同的消息给self
将创build一个无限循环,我相信你已经发现了。