Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically replace a method implementation in ObjC2?

I am trying to learn how to write plugins using SIMBL. I got my plugin to load with the target application, and also know the method that I wish to override. However, I am not able to use class_getInstanceMethod correctly based on snippets on the Internet. Have things changed in OSX 10.6 and/or ObjC2?

The following code from culater.net gives "Dereferencing pointer to incomplete type" on the second-last statement:

BOOL DTRenameSelector(Class _class, SEL _oldSelector, SEL _newSelector)
{
    Method method = nil;

    // First, look for the methods
    method = class_getInstanceMethod(_class, _oldSelector);
    if (method == nil)
        return NO;

    method->method_name = _newSelector;
    return YES;
}

Is there a complete example of how to override a method using SIMBL plugins? Thanks!

like image 436
Abhi Avatar asked Apr 07 '10 19:04

Abhi


2 Answers

The Obj-C runtime has changed in Objective-C 2, the code you quoted uses the older one.

(Well, on 32 bit apps, it's more correct to say there're two interfaces to the same runtime, depending on how you compile your binary; both work in the end. But it's easier to think that things changed in Objective-C 2. And you should use the newer APIs because it's easier to use, and it works both in 32 bit and 64 bit.)

New references are the Guide and the Reference. The basic change is that the internal struct is no longer public, is opaque. So you can't access its member directly. Instead, you need to use an API.

Typically things are easier in the new runtime. To replace an IMP, one just uses

IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types);

To get the type encoding, use

const char * method_getTypeEncoding(Method method);

against the original method you're replacing. In practice, that would be

method_getTypeEncoding(class_getInstanceMethod([SomeClass class], @selector(someSelector:you:want:to:replace:)));

To learn more about the runtime, I heartily recommend the wonderful series of blog posts Friday Q&A by Mike Ash.

Have fun and good luck!

like image 150
Yuji Avatar answered Nov 14 '22 23:11

Yuji


If you're looking to swizzle a method, you might consider using the method_exchangeImplementations function instead.

like image 40
Peter Hosey Avatar answered Nov 15 '22 00:11

Peter Hosey