更新时间:2022-03-15 21:36:18
您可以这样做,但不能使用类别。类别替换方法。 (警告,汽车比喻)如果你有一辆汽车,然后你摧毁那辆汽车并换上一辆新车,你还能使用旧车吗?不,因为它消失了,不再存在了。与类别相同。
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);