Dav*_*ong 10 objective-c nsinvocation imp
我正在寻找一种方法来NSInvocation调用特定的IMP.默认情况下,它调用IMP它可以找到的"最低" (即最近被覆盖的版本),但是我正在寻找一种方法让它IMP在继承链中从更高的位置调用它.在IMP我想要调用动态确定,否则我可以使用super关键字或类似的东西.
我的想法是使用-forwardInvocation:机制来捕获消息(简单且已经工作),然后改变IMP它,所以它转到一个既不是super实现也不是最远的后代实现的方法.(硬)
我发现远程关闭的唯一东西是AspectObjectiveC,但这需要libffi,这使得它与iOS兼容.理想情况下,我希望这是跨平台的.
有任何想法吗?
免责声明:我只是在试验
试试@bbum关于蹦床功能的想法
所以我觉得我已经把事情搞得一团糟了; 我有以下蹦床,通过正确添加class_addMethod(),它确实输入:
id dd_trampolineFunction(id self, SEL _cmd, ...) {
IMP imp = [self retrieveTheProperIMP];
self = [self retrieveTheProperSelfObject];
asm(
"jmp %0\n"
:
: "r" (imp)
);
return nil; //to shut up the compiler
}
Run Code Online (Sandbox Code Playgroud)
我已经验证了正确的自我和正确的IMP在JMP之前是正确的事情,并且_cmd参数也正确地进入.(换句话说,我正确地添加了这种方法).
然而,事情正在发生.我有时会发现自己跳到了零的方法(通常不正确的)self和_cmd.其他时候我只是在EXC_BAD_ACCESS的中途崩溃.想法?(自从我在汇编中做了很多事以来已经很久了...)我在x86_64上测试了这个.
鉴于您已经有了 IMP,您只需要一种方法来对所述 IMP 进行非常原始的方法调用。如果您愿意使用类似 NSInitation 的解决方案,那么您也可以构建一个类似的代理类。
如果我遇到这种情况,我会创建一个简单的代理类,其中包含要调用的 IMP 和目标对象(您需要设置参数self)。然后,我会在汇编中编写一个蹦床函数,它接受第一个参数,假设它是代理类的实例,抓取self,将其填充到保存参数 0 的寄存器中,抓取 IMP 和 *JMP 作为尾部调用。
有了 Trampoline,您就可以将该 Trampoline 添加为您想要转发到特定 IMP 的代理类上任何选择器的 IMP...
要实现像这样的任何类型的通用机制,关键是避免与重写堆栈帧有关的任何事情。避免 C ABI。避免争论。
| 归档时间: |
|
| 查看次数: |
1744 次 |
| 最近记录: |