How to call original implementation when overwriting a method with a category?

故事扮演 提交于 2019-11-30 09:59:33

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.

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.

So the bogus method would look like:

- (UIView *) bogusHitTest:(CGPoint)point withEvent:(UIEvent *)event {
  NSLog(@"executing: %@", NSStringFromSelector(_cmd));
  return [self bogusHitTest:point withEvent:event];
}

The code to swap the methods would be something along the lines of:

Method bogusHitTest = class_getInstanceMethod([UIView class], @selector(bogusHitTest:withEvent:));
Method hitTest = class_getInstanceMethod([UIView class], @selector(hitTest:withEvent:));
method_exchangeImplementations(bogusHitTest, hitTest);

What you want to do is called method swizzling : http://www.cocoadev.com/index.pl?MethodSwizzling

Unfortunately, no, there is no way to call the original implementation of a method that you override. Once you implement it in the category you have eliminated the original method.

Sending the same message to super should work in your method; it will call the method on the superclass as normal (if there is one).

Sending the same message to self will create an infinite loop, as I'm sure you've discovered.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!