0

ブロック クロージャーによって (const コピーによって) キャプチャできるスタック ベースの C 文字列 (つまり、char[]) を作成するクリーンな方法を見つけようとしています。基本的な考え方は次のとおりです。

char myString[16] = {0};
// ... put something into myString.
dispatch_block_t block = ^(){
    const size_t len = strlen(myString);
    if (len)
        NSLog(@"Not zero length");
};

しかし、それを行うと、次のコンパイラの苦情が発生します。

error: cannot refer to declaration with an array type inside block

char配列を構造体に入れることができると思いますが、それはちょっと醜いようです。より良い方法はありますか?

4

2 に答える 2

0

スタック割り当ての問題は、関数を終了するとスタック フレームが消えることですが、ブロック コードは残り、そのスタック フレーム内の変数を参照する可能性があります。ブロックは、__block で宣言された変数を含む、ブロックによって参照されるすべての値をヒープに割り当ててコピーすることにより、これを処理します。理論的には、静的サイズの配列をコピーできるはずですが、何らかの理由でサポートされていません。配列に関連して、私が認識していない技術的な問題が存在する可能性が非常に高いことに注意してください。

したがって、私が見る最も簡単な解決策は、malloc/free を使用することです。

char *myString = calloc(16,1);

dispatch_block_t block = ^(){
    const size_t len = strlen(myString);
    if (len)
        NSLog(@"Not zero length");
    free(myString);
};

ブロックを何度も再利用する必要がない限り、問題ありません。ブロックを再利用する必要がある場合は、ブロック内で参照できる NSData オブジェクトで myString をラップし、フリーを取り除きます。

char *myString = calloc(16,1);
NSData *myStringData = [NSData dataWithBytesNoCopy:myString length:16 freeWhenDone:YES];

dispatch_block_t block = ^(){
    const char *myString = myStringData.bytes;
    const size_t len = strlen(myString);
    if (len)
        NSLog(@"Not zero length");
};
于 2013-03-31T11:49:53.390 に答える