如何在覆盖带有类别的方法时调用原始实现? [英] How to call original implementation when overwriting a method with a category?

查看:103
本文介绍了如何在覆盖带有类别的方法时调用原始实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to figure out how things really work. So I thought when I would overwrite certain methods using categories, I would get interesting 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上调用。

super and self don't work here. Is there a way to call the original implementation of -hitTest:withEvent:? What I want is an NSLog every time -hitTest:withEvent: is called on an UIView.

它仅用于个人学习目的。我希望看到事件交付的实际效果。

It's just for personal learning purposes. I want to see the event delivery in action.

推荐答案

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

You can do it, but not using a category. A category replaces a method. (Warning, car analogy) If you have a car, and you destroy that car and replace it with a new car, can you still use the old car? No, because it is gone and does not exist anymore. The same with categories.

您可以做的是使用Objective-C运行时在运行时以不同的名称添加方法(例如, bogusHitTest:withEvent:),然后交换 hitTest的实现:withEvent: bogusHitTest:withEvent:。这样当代码调用 hitTest:withEvent:时,它将执行最初为 bogusHitTest编写的代码:withEvent:。然后,您可以让代码调用 bogusHitTest:withEvent:,这将执行原始实现。

What you could do is use the Objective-C runtime to add the method under a different name at runtime (say, "bogusHitTest:withEvent:"), then swap the implementations of hitTest:withEvent: and bogusHitTest:withEvent:. That way when the code calls hitTest:withEvent:, it's going to execute the code that was originally written for bogusHitTest:withEvent:. You can then have that code invoke bogusHitTest:withEvent:, which will execute the original implementation.

所以伪造方法如下:

- (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);

这篇关于如何在覆盖带有类别的方法时调用原始实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆