NSLog を実行した後、元の実装を呼び出す必要があると思います。そうでない場合は、クラスのカテゴリを使用してメソッドをオーバーライドできる場合があります。
メソッドをスウィズルするには、まず代替メソッドが必要です。私は通常、ターゲットクラスのカテゴリに次のようなものを入れます:
- (void)replacementReceiveMessage:(const struct BInstantMessage *)arg1 {
NSLog(@"arg1 is %@", arg1);
[self replacementReceiveMessage:arg1];
}
これは自分自身を再帰的に呼び出すように見えますが、古いバージョンを呼び出している間、呼び出しはこのメソッドを呼び出し、呼び出しReceiveMessage:
はこのメソッドを呼び出します。replacementReceiveMessage:
2 番目のステップは、ランタイム関数を使用して実際にスワップを実行することです。load
カテゴリを使用する利点は、作業を行うためにカテゴリで使用できることです。
+ (void)load {
SEL originalSelector = @selector(ReceiveMessage:);
SEL overrideSelector = @selector(replacementReceiveMessage:);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method overrideMethod = class_getInstanceMethod(self, overrideSelector);
if (class_addMethod(self, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(self, overrideSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, overrideMethod);
}
}
処理する必要がある 2 つのケースがあります。
- スウィズルしているメソッドが実際にスーパークラスで定義されている場合は、を使用
class_addMethod
して、の実装をターゲット クラスに追加するReceiveMessage:
必要があります。これは、置換実装を使用して行います。次に、スーパークラスの実装class_replaceMethod
に置き換えるために使用できるreplacementReceiveMessage:
ため、新しいバージョンは古いバージョンを正しく呼び出すことができます。
- メソッドがターゲット クラスで定義されている場合
class_addMethod
は失敗しますがmethod_exchangeImplementations
、新しいバージョンと古いバージョンを交換するために使用できます。