objective-ccocoamethodsswizzlingsimbl

How do I implement method swizzling?


I am trying to modify behaviour of a program (i dont have it's source) using SIMBL. I used class dump and found out that I need to overide an instance method

This method is in the class called controller. All I need to do is get the argument arg1 and thats it. Maybe NSLog it or post a notification... I read about method swizzling in objective-c but how can I use it?. I would need to refer to the class MessageController whose course i don't have.

Thanks!


Solution

  • 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: