复制多个方法swizzles的方法IMP [英] Copy a method IMP for multiple method swizzles

查看:138
本文介绍了复制多个方法swizzles的方法IMP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类设置,理想情况下会读取传入的任何类的方法,然后在运行时将它们全部映射到单个选择器上,然后将它们转发到原始选择器。

I have a class set up that ideally will read the methods of any class passed in and then map all of them to on single selector at runtime before forwarding them off to their original selector.

这现在可以正常工作,但我一次只能使用一种方法。问题似乎是,一旦我调整第一个方法,我的IMP捕获和转发方法现在已经与其他方法IMP交换。由于他们使用新交换的IMP替换其他IMP,所以进一步尝试这个搞砸了。

This does work right now, but I can only do it for one method at a time. The issue seems to be that once I swizzle the first method, my IMP to catch and forward the method has now been swapped with that other methods IMP. Any further attempts at this screw up because they use newly swapped IMP to replace the others.

1)所以我有MethodA,MethodB和CustomCatchAllMethod。

1)So I have MethodA, MethodB, and CustomCatchAllMethod.

2)我将MethodA与CustomCatchAllMEthod交换。 MethodA-> CustomCatchAllMethod,CustomCatchAllMethod-> MethodA

2)I swap MethodA with CustomCatchAllMEthod. MethodA->CustomCatchAllMethod, CustomCatchAllMethod->MethodA

3)现在我尝试使用CustomCatchAllMethod交换到MethodB,但由于CustomCatchAllMethod现在= MethodA,因此MethodB成为MethodA和MethodA - > MethodB。

3)Now I try to swap to MethodB with CustomCatchAllMethod as well, but since CustomCatchAllMethod now = MethodA, MethodB becomes MethodA and MethodA->MethodB.

那么如何为每个我想截取的新选择器获取/复制IMP的新实例?

So how do I get/copy a new instance of my IMP for each new selector I want to intercept?

以下是上述流程的粗略模型:

Here's a rough mockup of the above flow:

void swizzle(Class classImCopying, SEL orig){
 SEL new = @selector(catchAll:);
 Method origMethod = class_getInstanceMethod(classImCopying, orig);
 Method newMethod = class_getInstanceMethod(catchAllClass,new);
 method_exchangeImplementations(origMethod, newMethod);
}

//In some method elsewhere

//I want this to make both methodA and methodB point to catchAll:
swizzle(someClass, @selector(methodA:));
swizzle(someClass, @selector(methodB:));


推荐答案

这种常见的方法 - 混合模式只在你想要的时候有效用一个方法拦截一种方法。在你的情况下,你基本上是移动 catchAll:的实现而不是在任何地方插入它。

That common method-swizzling pattern only works when you want to intercept one method with one other. In your case you are basically moving the implementation for catchAll: around instead of inserting it everywhere.

要正确到你必须使用:

IMP imp = method_getImplementation(newMethod);
method_setImplementation(origMethod, imp);

这会给你留下一个问题:如何转发到原始实现?

这就是原始模式使用 exchangeImplementations for。

This leaves you with one problem though: how to forward to the original implementation?
That is what the original pattern used exchangeImplementations for.

在你的情况下你可以:


  • 保留一张原始 IMP 的表格或

  • 使用一些公共前缀重命名原始方法,因此您可以从 catchAll:

  • keep a table of the original IMPs around or
  • rename the original methods with some common prefix, so you can build a call to them from catchAll:

请注意,当您想通过相同的方法转发所有方法时,您只能处理相同的方法。

Note that you can only handle methods of the same arity when you want to forward everything through the same method.

这篇关于复制多个方法swizzles的方法IMP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆