我想为
objective-c中的对象构建一个小插件系统.
@H_301_2@现在我陷入了我想要动态地(在运行时)为对象中的每个可用功能添加一行代码的地步.
@H_301_2@我已经玩过运行时库,但还没有找到解决方案.
@H_301_2@到目前为止我尝试过的是:
>使用“swizzle Method”之一更改每个函数的IMP
>使用“旧”实现创建一个新方法,并将名称更改为类似“___name”的模式 @H_301_2@在这个解决方案中,我陷入了第3点.我还没有设法动态创建一个完整的新方法. @H_301_2@有没有人可以帮助我解决上面的问题,或者有一个“捕获所有方法功能”的另一个解决方案. @H_301_2@最好的是类似forwardInvocation,它也捕获已经定义的函数. @H_301_2@谢谢你的帮助!
id (^impyBlock)(id,id,... ) = ^(id self_,id arguments,...) { // My custom code for every function here id (*func)(__strong id,SEL,...) = (id (*)(__strong id,...))imp; return func(obj,s,arguments); }; id (*impyFunct)(id,...) = imp_implementationWithBlock(impyBlock); method_setImplementation(mList[i],impyFunct);@H_301_2@我的问题是,当有多个参数时,我没有机会将它们传递给“func()”. AFAIK这在C中是不可能的. @H_301_2@我想到的另一个解决方案是通过方法调配来做一些魔术. @H_301_2@步骤: @H_301_2@>创建一个“swizzle方法”,它只调用我的自定义代码并在之后调用原始方法(通过命名方案)
>使用“swizzle Method”之一更改每个函数的IMP
>使用“旧”实现创建一个新方法,并将名称更改为类似“___name”的模式 @H_301_2@在这个解决方案中,我陷入了第3点.我还没有设法动态创建一个完整的新方法. @H_301_2@有没有人可以帮助我解决上面的问题,或者有一个“捕获所有方法功能”的另一个解决方案. @H_301_2@最好的是类似forwardInvocation,它也捕获已经定义的函数. @H_301_2@谢谢你的帮助!
解决方法
Lemme把这分为两部分,因为我无法将你的两个问题联系起来.
@H_301_2@I.使用“旧”实现创建一个新方法,并将名称更改为类似“___name”的模式
@H_301_2@这很容易,虽然我不明白如何解决你的问题.你仍然无法将可变参数函数参数传递给这样的方法(你是对的,不能在C中完成).
IMP swapImpForSelector(Class cls,SEL sel,IMP newImp) { Method m = class_getInstanceMethod(cls,sel); IMP oldImp = method_setImplementation(m,newImp); NSString *newSel = [NSString stringWithFormat:@"__prefixed_%@",NSStringFromSelector(sel)]; const char *type = method_getTypeEncoding(m); class_addMethod(cls,NSSelectorFromString(newSel),oldImp,type); return oldImp; }@H_301_2@II.如果你想在函数之间传递可变参数,你可能需要回到沉重的程序集hackage.幸运的是,一些聪明人已经为你做了这件事. @H_301_2@使用NSInvocation class,或者如果不够,那么libffi甚至更低.