Objective-C:在带有参数的块上是否有-invoke?

时间:2011-09-20 00:48:26

标签: objective-c objective-c-blocks

您可能知道,块占用-invoke

void(^foo)() = ^{
    NSLog(@"Do stuff");
};

[foo invoke];  // Logs 'Do stuff'

我想做以下事情:

void(^bar)(int) = ^(int k) {
     NSLog(@"%d", k);
};

[bar invokeWithParameters:7];   // Want it to log '7', but no such instance method

普通无参数-invoke适用于bar,但它打印出无意义的值。

我找不到这种可以发送到块的直接消息,也无法找到描述块如何占用-invoke的原始文档。 是否有块接受的消息列表?

(是的,我尝试使用class_copyMethodList从运行时提取方法列表;似乎没有。)

编辑:是的,我也知道以通常的方式调用块(bar(7);)。我真正追求的是一个方法的选择器,我可以提供给不带块的库代码(本身)。

2 个答案:

答案 0 :(得分:11)

您可以像函数一样调用它:

bar(7);

文档中甚至有一个使用完全相同签名的示例。请参阅Declaring and Using a Block

关于块行为的最佳参考是Block Language Specification(RTF)文档。这提到了某些支持的方法(复制,保留等),但没有提到-invoke方法。

答案 1 :(得分:5)

块的定义是块可以接收的“消息”的总和,就调用参数/ ABI而言。

这有几个原因:

首先,块不是函数,块指针不是函数指针。它们不能互换使用。

其次,如果要正确编码参数,那么C ABI就是 在编译调用站点时声明函数begin被调用。

另一种方法是使用类似NSInvocation的东西,它允许单独编码参数,但即便如此,仍需要为每个单独的参数提供完整的C ABI知识。

最终,如果你可以编译一个包含所有参数的调用站点,无论是Objective-C方法还是函数调用,为了使编译器满意所需的保真度,你可以将该调用站点转换为调用块。

即。除非你澄清一下你的问题,否则由于C ABI的变幻莫测,你所要求的要么已经得到支持,要么几乎不可能。