如何在覆盖带有类别的方法时调用原始实现?

时间:2010-11-28 00:53:10

标签: ios objective-c objective-c-category swizzling method-swizzling

我试着弄清楚事情是如何运作的。所以我想当我用类别覆盖某些方法时,我会得到有趣的NSLog。

@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上调用。

这仅用于个人学习目的。我希望看到活动的实施。

3 个答案:

答案 0 :(得分:14)

您可以这样做,但不能使用类别。类别替换方法。 (警告,汽车比喻)如果你有一辆汽车,并且你摧毁了那辆汽车并换上新车,你还能使用这辆旧车吗?不,因为它消失了,不再存在了。与类别相同。

你可以做的是使用Objective-C运行时在运行时以不同的名称添加方法(比如“bogusHitTest:withEvent:”),然后交换hitTest:withEvent:和{{1的实现}}。这样,当代码调用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];
}

答案 1 :(得分:3)

您想要做的是称为方法调配:http://www.cocoadev.com/index.pl?MethodSwizzling

答案 2 :(得分:0)

不幸的是,不,没有办法调用你覆盖的方法的原始实现。在类别中实现它后,您已经删除了原始方法。

super发送相同的消息应该适用于您的方法;它将正常调用超类上的方法(如果有的话)。

self发送相同的消息将创建一个无限循环,因为我相信你已经发现了。