Я хочу реализовать функцию «Исправить и продолжить», которая была в Xcode 3.
КОНТЕКСТ:
Основная идея такова: когда мне нужно "быстро что-то исправить", я не перекомпилирую проект. Я компилирую небольшой 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
.
ОБНОВЛЕНИЕ: добавлен заменяющий код реализации.