理想的には、渡されたクラスのメソッドを読み取り、実行時にすべてを単一のセレクターにマップしてから、元のセレクターに転送するように設定されたクラスがあります。
これは現在機能しますが、一度に実行できるのは1つのメソッドのみです。問題は、最初のメソッドをスウィズすると、メソッドをキャッチして転送するIMPが他のメソッドIMPと交換されたことにあるようです。新しく交換されたIMPを使用して他のIMPを置き換えるため、この失敗をさらに試みることはできません。
1)つまり、MethodA、MethodB、およびCustomCatchAllMethodがあります。
2)MethodAをCustomCatchAllMEthodと交換します。MethodA-> CustomCatchAllMethod、CustomCatchAllMethod-> MethodA
3)CustomCatchAllMethodを使用してMethodBにスワップしようとしましたが、CustomCatchAllMethodがMethodAになっているため、MethodBはMethodAおよびMethodA->MethodBになります。
では、インターセプトする新しいセレクターごとに、IMPの新しいインスタンスを取得/コピーするにはどうすればよいですか?
上記のフローの大まかなモックアップは次のとおりです。
void swizzle(Class classImCopying, SEL orig){
SEL new = @selector(catchAll:);
Method origMethod = class_getInstanceMethod(classImCopying, orig);
Method newMethod = class_getInstanceMethod(catchAllClass,new);
method_exchangeImplementations(origMethod, newMethod);
}
//In some method elsewhere
//I want this to make both methodA and methodB point to catchAll:
swizzle(someClass, @selector(methodA:));
swizzle(someClass, @selector(methodB:));