是否可以直接将函数指针作为块参数传递?

时间:2012-11-05 13:46:47

标签: objective-c objective-c-blocks

假设我有一个需要阻止的函数:

void foo(Foo (^block)(Bar));

并说我有一个具有相同签名的函数,除了不是块:

Foo myFunction(Bar);

我可以这样做:

foo(^(Bar bar) { return myFunction(bar); });

但我宁愿这样做,如果有效的话,这将是相同的:

foo(&myFunction);

如果我尝试,XCode说:

No matching function for call to 'foo'

一个块是一个函数指针和一些上下文,所以在这个级别上,想要使用普通函数指针作为具有空上下文的块似乎是合理的。有可能吗?

4 个答案:

答案 0 :(得分:9)

  

一个块是一个函数指针和一些上下文,所以就这样   想要使用普通函数指针作为一个级别似乎是合理的   阻止空上下文。有可能吗?

问题是,一个块不是一个函数指针和一些上下文

块在编译期间捕获可执行代码,并在执行期间捕获状态。可执行代码遵循C ABI在传递参数方面,就像方法调用一样,它有一些非常具体的要求。将它转换为C函数声明,返回BOOL并获取单个int参数的块将如下所示:

BOOL blockLikeFunc(void *block, int arg) { ... }

也就是说,块的“函数”的第一个参数必须是指向块本身的指针。

因此,不,你不能只是撕掉块的“函数”指针并将其转换为C函数或从C函数转换它。

答案 1 :(得分:0)

  

但是块是一个函数指针

除非它不是。如果要将函数指针作为参数传递,请尝试:

int FooDouble(int x)
{
    return x * 2;
}

- (int)callFunction:(int (*)(int))function withArgument:(int)arg
{
    return function(arg);
}

NSLog(@"%d", [self callFunction:FooDouble withArgument:21]);

这会输出42

答案 2 :(得分:0)

你提交了常规函数指针(c)的东西 NOT块

答案 3 :(得分:0)

{{1}}