Как вызвать оригинальную реализацию при перезаписи метода с категорией?
-
28-09-2019 - |
Вопрос
Я пытаюсь выяснить, как действительно работает. Поэтому я подумал, когда я перезапишу определенные методы, используя категории, я бы получил интересные NSLogs.
@implementation UIView(Learning)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"-hitTest:withEvent: event=%@", event);
return [self hitTest:point withEvent:event];
}
@end
Супер и я не работаю здесь. Есть ли способ назвать оригинальную реализацию -Hittest: Covent :? То, что я хочу, это Nslog каждый раз --hittest: osevent: называется 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);
Другие советы
То, что вы хотите сделать, это называется методом Swizled: http://www.cocoadev.com/index.pl?methodswizzling.
К сожалению, нет, нет способа позвонить в оригинальную реализацию метода, который вы переопределяете. Как только вы реализуете его в категории, вы устранили оригинальный метод.
Отправка такого же сообщения super
следует работать в вашем методе; Это позвонит методу на суперкласс как обычно (если есть один).
Отправка такого же сообщения self
Создаю бесконечный цикл, как я уверен, вы обнаружите.