7

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

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

4 回答 4

9

块是带有一些上下文的函数指针,因此在那个级别上,希望将普通函数指针用作具有空上下文的块似乎是合理的。可能吗?

但是,问题在于块不是带有一些上下文的函数指针

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

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

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

因此,不,您不能只删除块的“函数”指针并将其转换为/从 C 函数中转换。

于 2012-11-05T16:07:43.793 回答
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.

于 2012-11-05T13:49:55.060 回答
0

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

于 2015-06-06T21:57:11.330 回答
0
@import Foundation;

@implementation NSObject(extra)
+ (int)callFunction:(int (^)(int))function withArgument:(int)arg
{
    return function(arg);
}
@end;

int main() {
    @autoreleasepool {
        NSLog(@"doubleIt(3) returns %d", [NSObject callFunction:^(int param) { return param * param; } withArgument:3]);
    } return 0;
}
于 2015-06-06T22:00:32.593 回答