Я хочу "реализовать" Исправить и продолжить функциональность ", которая была в Xcode 3.
КОНТЕКСТ
Основная идея: Когда мне нужно "Fix something fast", я не перекомпилирую проект. Я компилирую небольшой Attacker class
с помощью "обновленной" реализации метода, загружая его в память и заменяя метод VictimClass, который имеет реализацию incorrect
во время выполнения.
Я думаю, что этот метод будет работать быстрее, чем полная перекомпиляция проекта.
Когда я закончил с исправлениями, я просто копирую источник метода Attacker class
в Victim class
.
ПРОБЛЕМА
В настоящий момент я не знаю, как правильно вызвать [super ...]
в классе Attacker.
Например, у меня есть VictimClass
@interface VictimClass : UIView @end
@implementation VictimClass
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
}
@end
@interface AttackerClass : NSObject @end
@implementation AttackerClass
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
[self setupPrettyBackground];
}
@end
....
// EXCHANGE IMPLEMENTATIONS
Method m = class_getInstanceMethod([AttackerClass class], @selector(drawRect:));
const char * types = method_getTypeEncoding(m);
IMP attackerImp = method_getImplementation(m);
class_replaceMethod([VictimClass class], @selector(drawRect:), attackerImp, types);
// Invoking drawRect on Victim
VictimClass * view = /* */;
[view setNeedsDisplay];
В этот момент, когда будет вызываться метод drawRect:
, это приведет к исключению, так как drawRect:
будет вызван в классе NSObject, но не в классе UIView
Итак, мой вопрос: как правильно называть [super drawRect:]
в AttackerClass, чтобы иметь возможность правильно обменивать реализацию во время выполнения?
Основная идея - предоставить способ правильно заменить любой метод класса Victim методом класса Attacker. Как правило, вы не знаете, суперкласс Victim class
.
UPDATE: добавлена замена кода реализации.