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関数宣言に変換すると、aを返し、BOOL単一の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 に答える