我试图弄清楚事情的真正工作方式。因此,我认为当我使用类别覆盖某些方法时,我会得到有趣的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 正如我确定您发现的那样,将创建一个无限的循环。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top