代码之家  ›  专栏  ›  技术社区  ›  Jonathan Sterling

从Objective-C块创建IMP

  •  19
  • Jonathan Sterling  · 技术社区  · 15 年前

    这个 IMP 据我所知,objective-c中的type表示一个函数指针。有没有办法 进口 从块指针?谢谢你的意见。

    2 回复  |  直到 12 年前
        1
  •  27
  •   bbum    13 年前

    既然写了这篇文章,现在iOS和MacOSX中就有了API,允许块直接转换成IMP。我写了一篇文章 weblog post 描述API(imp ou implementationwithblock())。


    块实际上是一种结构,它包含一点元数据、对块中包含的代码的引用以及块中捕获的常量复制数据的副本。

    因此,不,没有办法直接在 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)实施蹦床冲击,类似于:

    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 并且喜欢)

    Caveats:

    • 这被输入stackoverflow。真正的代码是相似的,但可能略有不同。

    • [implementingblock copy]非常关键;块在堆栈上开始生命(通常)

        2
  •  10
  •   Clay Bridges    12 年前

    我相信MikeAsh,在LandonFuller的帮助下,已经解决了一般情况下的问题,包括iOS,这是很困难的。他上了一节课 github 它将把一个块变成一个函数指针。

    你可能还想授予 announcement 以及一些有趣的关于可可未绑定的后续讨论。

    更新:现在有 imp_implementationWithBlock() 如上所述。

    推荐文章