IMP
据我所知,Objective-C 中的类型表示一个函数指针。有没有办法IMP
从块指针中创建一个?谢谢你的想法。
2 回答
由于这是编写的,现在 iOS 和 Mac OS X 中的 API 允许将块直接转换为 IMP。我写了一篇描述 API 的博客文章(imp_implementationWithBlock())。
块实际上是一个结构,它包含一些元数据、对块中包含的代码的引用以及在块中捕获的 const 复制数据的副本。
因此,不,没有办法直接在 anIMP
和 Block 引用之间进行映射。
当对块的调用被编译时,编译器会发出一个蹦床来设置堆栈帧,然后跳转到块内的可执行代码。
但是,您可以做的是创建一个像蹦床一样工作的 IMP。对于以下内容,您将需要一个特定的 IMP 来调用每组参数和返回类型。如果您需要使其通用,则需要使用程序集。
为此,我为每个类的实例设置了唯一的块实例。如果你想要一个通用块在所有实例中起作用,请为SEL
每个类构建一个 -> 块的散列。
(1) 使用关联引用机制关联块以充当 IMP。就像是:
void (^implementingBlock)(id s, SEL _c, int v) = ^(id s, SEL _c, int v) {
// do something here
}
objc_setAssociatedObject(obj, SELToImp, [implementingBlock copy]));
(2) 实现一个类似这样的蹦床 IMP:
void void_id_sel_intTramp(id self, SEL _cmd, int value) {
int (^block)(id s, SEL _c, int v) = objc_getAssociatedObject(self, _cmd);
block(self, _cmd, value);
}
(3) 通过 Objective-C 运行时的 API 将上述蹦床填充到任何选择器中(参见method_setImplementation
和喜欢)
注意事项:
这是输入到 StackOverflow 中的。真正的代码将相似,但可能略有不同。
[implementingBlock copy] 很关键;块在堆栈上开始生命(通常)