Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当用类别覆盖方法时,如何调用原始实现?_Ios_Objective C_Objective C Category_Swizzling_Method Swizzling - Fatal编程技术网

Ios 当用类别覆盖方法时,如何调用原始实现?

Ios 当用类别覆盖方法时,如何调用原始实现?,ios,objective-c,objective-c-category,swizzling,method-swizzling,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]; } @en

我试图弄清楚事情到底是怎么回事。所以我想,当我使用类别覆盖某些方法时,我会得到有趣的nslog

@implementation UIView(Learning)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"-hitTest:withEvent: event=%@", event);
    return [self hitTest:point withEvent:event];
}
@end
super和self在这里不起作用。是否有方法调用-hitTest:withEvent:的原始实现?我想要的是每次在UIView上调用hitTest:withEvent:时都有一个NSLog


这只是为了个人学习的目的。我希望看到事件交付的实际操作。

不幸的是,没有办法调用您重写的方法的原始实现。一旦在类别中实现了它,您就消除了原始方法

super
发送相同的消息应该在您的方法中起作用;它将调用超类上的正常方法(如果有)


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

您要做的就是方法切换:

您可以这样做,但不使用类别。类别替换方法。(警告,汽车类比)如果你有一辆汽车,你毁掉了那辆汽车,换上一辆新车,你还能用那辆旧车吗?不,因为它已经不存在了。类别也是如此

您可以使用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);

Super在类别中不起作用,因为您不是在同一个类中调用它,而是在类的Super中调用它。因此,在本例中,super是一个UIResponder,它没有hitTest:withEvent方法。调用self只会导致一个无限循环,因为您正在覆盖“self”的hitTest:withEvent。我的注释在这里看起来有点不合适,但在前面的注释删除了他的之前是有意义的。正如Adam所说,这种方式是不可能的,但您可以看看方法Swizzling。这里有一个很好的例子:我不确定,但这篇文章似乎有点过时。DaveDelong发布了一个解决方案,该解决方案使用的代码非常少。无论如何,谢谢:-)@BugAlert,请注意,我的代码是方法swizzling。链接的文章只是提供了更多关于它的信息。:)