开发者

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!


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!


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜