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

Abh*_*bhi 6 cocoa objective-c

我正在尝试学习如何使用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;
}
Run Code Online (Sandbox Code Playgroud)

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

Yuj*_*uji 7

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

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

新参考文献是指南参考.基本的变化是内部struct不再公开,不透明.因此您无法直接访问其成员.相反,您需要使用API​​.

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

IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types);
Run Code Online (Sandbox Code Playgroud)

要获取类型编码,请使用

const char * method_getTypeEncoding(Method method);
Run Code Online (Sandbox Code Playgroud)

反对您正在替换的原始方法.在实践中,那将是

method_getTypeEncoding(class_getInstanceMethod([SomeClass class], @selector(someSelector:you:want:to:replace:)));
Run Code Online (Sandbox Code Playgroud)

要了解更多有关运行时,我衷心推荐精彩的系列博客文章周五Q&A由Mike灰.

玩得开心,祝你好运!


Pet*_*sey 5

如果您想要调整方法,可以考虑使用method_exchangeImplementations函数.

  • 否.方法调配的工作原理是因为选择器的实现是在发送消息时动态查找的 - 即在运行时.有一个名称,它是选择器,一个值,它是实现,并且swizzling将一个值交换为另一个值,与更改字典中的值不同.功能不会动态查找; 加载可执行文件时地址被绑定并在此后保持固定,并且调用直接转到该地址,因此无需重新映射. (2认同)