Как вызвать оригинальную реализацию при перезаписи метода с категорией?

StackOverflow https://stackoverflow.com/questions/4294753

Вопрос

Я пытаюсь выяснить, как действительно работает. Поэтому я подумал, когда я перезапишу определенные методы, используя категории, я бы получил интересные 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 Создаю бесконечный цикл, как я уверен, вы обнаружите.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top