Xcode 3にあった「Fix and continue機能」を実装したい。
コンテキスト:
主なアイデアは次のとおりです。「何かをすばやく修正する」必要がある場合、プロジェクトを再コンパイルするのではありません。Attacker class
「更新された」メソッド実装で小さくコンパイルし、それをメモリにロードしincorrect
、実行時に実装されている VictimClass のメソッドを置き換えています。この方法は、プロジェクト全体を再コンパイルするよりも速く機能すると思います。
修正が完了したら、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];
この時点で、メソッドが呼び出されると、 UIView クラスではなく NSObject クラスで呼び出されるdrawRect:
ため、例外が発生します。drawRect:
それで、私の質問は、[super drawRect:]
実行時に実装を正しく交換できるようにするために、どのように AttackerClass を正しく呼び出すかということです。
主なアイデアは、Victim クラスの任意のメソッドを攻撃者のクラス メソッドに正しく置き換える方法を提供することです。一般に、 のスーパークラスはわかりませんVictim class
。
更新: 実装コードの置き換えが追加されました。