I'm guessing you need to call the original implementation after doing your NSLog; if not, you may be able to just use a category on the class to override the method.
To swizzle the method, first you need a replacement method. I usually put something like this in a category on the target class:
- (void)replacementReceiveMessage:(const struct BInstantMessage *)arg1 {
NSLog(@"arg1 is %@", arg1);
[self replacementReceiveMessage:arg1];
}
This looks like it will recursively call itself, but it won't because we're going to swap things around so calling ReceiveMessage:
calls this method while calling replacementReceiveMessage:
calls the old version.
The second step is to use the runtime functions to actually perform the swap. The advantage of using a category is that you can use load
in the category to do the work:
+ (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);
}
}
There are two cases that need to be handled:
- If the method we're swizzling is actually defined in a superclass, we have to use
class_addMethod
to add an implementation of ReceiveMessage:
to the target class, which we do using our replacement implementation. Then we can use class_replaceMethod
to replace replacementReceiveMessage:
with the superclass's implementation, so our new version will be able to correctly call the old.
- If the method is defined in the target class,
class_addMethod
will fail but then we can use method_exchangeImplementations
to just swap the new and old versions.