从Objective-C块创建IMP [英] Creating an IMP from an Objective-C block

查看:164
本文介绍了从Objective-C块创建IMP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Objective-C中的 IMP 类型代表一个函数指针,就像我所理解的。是否有任何方法从块指针创建 IMP ?感谢您的想法。

The IMP type in Objective-C represents a function pointer, as far I as understand. Is there any way to make an IMP from a block pointer? Thanks for your ideas.

推荐答案

由于这是写入的,现在有iOS和Mac OS X中的API,直接进入IMPs。我写了一个网络日志帖子,说明API(imp_implementationWithBlock())。

Since this was written there is now API in iOS and Mac OS X that allows Blocks to be turned into IMPs directly. I wrote up a weblog post describing the API (imp_implementationWithBlock()).

一个块实际上是一个包含一点元数据,到块中包含的代码和在块内捕获的const复制数据的副本。

A block is effectively a structure that contains a bit of metadata, a reference to the code contained within the block and a copy of the const-copied data captured within the block.

因此,没有办法直接映射到 IMP 和块引用。

Thus, no, there is no way to directly map between an IMP and a Block reference.

编译调用块时,编译器会生成一个蹦床堆栈框架然后跳转到块内的可执行代码。

When a call to a block is compiled, the compiler emits a trampoline that sets up the stack frame and then jumps to the executable code within the block.

你可以做的是创建一个像蹦床一样的IMP。对于以下,你将需要一个特定的IMP为每组参数&返回类型被调用。如果你需要使这个泛型,你需要使用程序集。

What you can do, though, is create an IMP that acts like that trampoline. For the following, you will need one specific IMP for each set of arguments & return types to be called. If you need to make this generic, you'll need to use assembly.

为此,我为类的每个实例设置唯一的块实例。如果你想有一个泛型块在所有实例之间,建立 SEL - >每个类的块。

For this, I'm setting up unique block instances per instance of the class. If you want to have a generic block that acts across all instances, build a hash of SEL -> block per class.

(1)使用关联的引用机制将块关联到IMPs。类似:

(1) Associate blocks to act as IMPs using the associated references mechanism. Something like:

void (^implementingBlock)(id s, SEL _c, int v) = ^(id s, SEL _c, int v) {
     // do something here
}

objc_setAssociatedObject(obj, SELToImp, [implementingBlock copy]));

(2)实现一个trampoline IMP,如下所示:

(2) implement a trampoline IMP something like this:

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 等)

(3) stuff the above trampoline in for any selector via the Objective-C runtime's API (see method_setImplementation and like)

注意:


  • 这是输入到StackOverflow。

  • this was typed into StackOverflow. The real code will be similar, but likely slightly different.

[implementingBlock copy]是非常重要的。块通常在堆栈上启动生命(通常)

the [implementingBlock copy] is critical; Blocks start life on the stack (usually)

这篇关于从Objective-C块创建IMP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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