如何动态替换ObjC2中的方法实现?

时间:2010-04-07 19:50:38

标签: objective-c cocoa

我正在尝试学习如何使用SIMBL编写插件。我得到了我的插件来加载目标应用程序,并且还知道我想要覆盖的方法。但是,我无法根据Internet上的代码段正确使用class_getInstanceMethod。在OSX 10.6和/或ObjC2中有变化吗?

culater.net中的以下代码在倒数第二个语句中给出了“取消引用指向不完整类型的指针”:

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;
}

是否有完整的示例说明如何使用SIMBL插件覆盖方法?谢谢!

2 个答案:

答案 0 :(得分:7)

Obj-C运行时在Objective-C 2中已更改,您引用的代码使用较旧的代码。

(嗯,在32位应用程序上,说同一个运行时有两个接口更正确,这取决于你编译二进制文件的方式;最终都可以工作。但是更容易认为Objective中的内容发生了变化-C 2.你应该使用更新的API,因为它更容易使用,并且它可以在32位和64位下工作。)

新引用为the Guidethe Reference。基本的变化是内部struct不再公开,不透明。因此您无法直接访问其成员。相反,您需要使用API​​。

通常情况下,新运行时更容易。要替换IMP,只需使用

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

要获取类型编码,请使用

const char * method_getTypeEncoding(Method method);

反对你要替换的原始方法。在实践中,那将是

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

要了解有关运行时的更多信息,我衷心推荐Mike Ash撰写的精彩系列博文Friday Q&A

玩得开心,祝你好运!

答案 1 :(得分:5)

如果您希望swizzle a method,可以考虑改用the method_exchangeImplementations function