gpt4 book ai didi

objective-c - 为多个方法调配复制一个方法 IMP

转载 作者:可可西里 更新时间:2023-11-01 05:47:07 26 4
gpt4 key购买 nike

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

这现在确实有效,但我一次只能对一种方法执行此操作。问题似乎是,一旦我调整了第一个方法,我的 IMP 来捕获和转发该方法现在已与其他方法 IMP 交换。任何进一步的尝试都会搞砸,因为他们使用新交换的 IMP 来替换其他的。

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

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

3) 现在我也尝试使用 CustomCatchAllMethod 切换到 MethodB,但是由于 CustomCatchAllMethod 现在 = MethodA,MethodB 变为 MethodA 和 MethodA->MethodB。

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

这是上述流程的粗略模型:

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: 的实现,而不是在任何地方插入它。

为了正确地做到这一点,你必须使用:

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

但这给您留下了一个问题:如何转发到原始实现?
这就是原始模式使用 exchangeImplementations 的目的。

在您的情况下,您可以:

  • 保留原始 IMP 的表格或
  • 用一些通用前缀重命名原始方法,这样您就可以从 catchAll:
  • 构建对它们的调用

请注意,当您希望通过相同的方法转发所有内容时,您只能处理相同数量的方法。

关于objective-c - 为多个方法调配复制一个方法 IMP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9242571/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com