9

この質問は、次の質問を参照しています: ブロックを使用してコールバック ロジックを簡素化する方法は?

私のヘッダーにはこれらのtypedefがあります

typedef void (^StuffDoneBlock)(NSDictionary * parsedData);
typedef void (^StuffFailedBlock)(NSError * error);

そして初期化で

stuffDoneCallback = Block_copy(done);
StuffFailedCallback = Block_copy(error);

この論文では、Block_copy は不要であると述べています。ただし、ブリッジキャストが必要です。コンパイラ メッセージは次のとおりです。

error: cast of block pointer type 'StuffDoneBlock' (aka 'void (^)(NSDictionary *__strong)') to C pointer type 'const void *' requires a bridged cast [4]
         stuffDoneCallback = _bridge(Block_copy(done));
                                     ^~~~~~~~~~~~~~~~
/Developer-4.2/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/include/Block.h:60:61: note: instantiated from:
 #define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
4

1 に答える 1

22

まず、なぜあなたも使用しているのBlock_copy()ですか?生の C を書いているのでない限り、-copy代わりに のようにブロックを呼び出す必要があります[done copy]。第 2 に、ARC は初期化スコープ [1] を超えて存続する必要があるブロックをコピーするため、-copyもう呼び出す必要はありません。唯一の「例外」は、ブロック タイプのプロパティにはcopy属性が必要なことです。

[1]: ここでは説明が必要なようです。ARC は、ブロックが初期化スコープを超えて存続する必要があることをコンパイラが認識した場合にのみ、ブロックを暗黙的にコピーします。これは基本的に、現在のスコープをエスケープする変数 (親スコープで宣言されたスタック変数、インスタンス変数、静的など) に割り当てられた場合を意味します。ただし、メソッド/関数に引数として渡された場合、コンパイラは自動コピーを行いません。dispatch_async()スタック フレーム ( 、完了ブロックなど) を超えてブロックを保持する必要があるブロック対応のメソッド/関数がそれらをコピーするため、通常、これは問題になりません。ただし、ブロックを認識しないAPI ( などNSArray) はブロックを暗黙的にコピーしません。-retainトリックを行います。ブロックを非ブロック対応 API に渡し、ブロックが現在のスコープを超えて存続する必要がある場合は、明示的な を使用する必要があります-copy

于 2011-10-11T21:09:04.480 に答える