复制多个方法swizzles的方法IMP
我有一个类设置,理想情况下,将读取传入的任何类的方法,然后映射到单个select器在运行时,然后将它们转发到它们的原始select器。
这现在可以工作,但是我一次只能用一种方法来做。 这个问题似乎是,一旦我调整了第一种方法,我的IMP捕捉和转发方法现在已经与其他IMP方法交换。 任何进一步的尝试在这个搞砸了,因为他们使用新交换IMP来取代其他人。
1)所以我有MethodA,MethodB和CustomCatchAllMethod。
2)我将MethodA与CustomCatchAllMEthod交换。 MethodA-> CustomCatchAllMethod,CustomCatchAllMethod-> MethodA
3)现在我尝试用CustomCatchAllMethod交换到MethodB,但是现在CustomCatchAllMethod = MethodA,MethodB变成MethodA,MethodA-> MethodB。
那么如何获取/复制我想要拦截的每个新select器的IMP的新实例?
以下是上述stream程的粗略模型:
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:
around而不是将它插入到任何地方。
为了正确的这个,你必须使用:
IMP imp = method_getImplementation(newMethod); method_setImplementation(origMethod, imp);
这给你留下了一个问题:如何转发到原来的实现?
这就是使用exchangeImplementations
的原始模式。
在你的情况下,你可以:
- 保留一个原始的
IMP
或附近的桌子 - 用一些常用的前缀重命名原始的方法,所以你可以从
catchAll:
构build一个对它们的调用catchAll:
请注意,只有当您想通过相同的方法转发所有内容时,您才能处理相同方法的方法。
你可以用块捕获原始的IMP,得到块的IMP并将其设置为方法的实现。
Method method = class_getInstanceMethod(class, setterSelector); SEL selector = method_getName(method); IMP originalImp = method_getImplementation(method); id(^block)(id self, id arg) = ^id(id self, id arg) { return ((id(*)(id, SEL, id))originalImp)(self, selector, arg); }; IMP newImp = imp_implementationWithBlock(block); method_setImplementation(method, newImp);
- 如何查看XCode 4中所有文件的编译错误?
- 在Swift中为一个控制器属性赋值
- 来自.xib的iOS自定义UIView
- 基于NSURLSession的networking模式
- inheritanceUIView以绘制Quartz
- 在UIPageViewController中,当“pageViewController:viewControllerBeforeViewController”被调用?
- 在Swift中从另一个ViewController访问variables
- 另一个视图控制器上的UIAlertView崩溃问题
- 核心数据和GCD:将正确的托pipe对象上下文传递给自定义NSManagedObjects