Block小テスト

3429 ワード

いくつかのblcokの小さいテスト、あなたがblockに対してどのように掌握することを見ます
例1
void exampleA() {
  char a = 'A';
  ^{
    printf("%c
", a);   }(); }

この例:A.常に正常に動作するB.ARCを使用している場合にのみ正常に動作するC.ARCを使用しないと正常に動作しないD.常に正常に動作しない例2:
void exampleB_addBlockToArray(NSMutableArray *array) {
  char b = 'B';
  [array addObject:^{
    printf("%c
", b);   }]; } void exampleB() {   NSMutableArray *array = [NSMutableArray array];   exampleB_addBlockToArray(array);   void (^block)() = [array objectAtIndex:0];   block(); }

A.常に正常に動作するB.ARCを使用した場合のみ正常に動作するC.ARCを使用しないと正常に動作しないD.常に正常に動作しない例3
void exampleC_addBlockToArray(NSMutableArray *array) {
  [array addObject:^{
    printf("C
");   }]; } void exampleC() {   NSMutableArray *array = [NSMutableArray array];   exampleC_addBlockToArray(array);   void (^block)() = [array objectAtIndex:0];   block(); }

A.常に正常に動作するB.ARCを使用した場合のみ正常に動作するC.ARCを使用しないと正常に動作しないD.常に正常に動作しない例4
typedef void (^dBlock)();
 
dBlock exampleD_getBlock() {
  char d = 'D';
  return ^{
    printf("%c
", d);   }; } void exampleD() {   exampleD_getBlock()(); }

A.常に正常に動作するB.ARCを使用した場合のみ正常に動作するC.ARCを使用しないと正常に動作しないD.常に正常に動作しない例5
typedef void (^eBlock)();
 
eBlock exampleE_getBlock() {
  char e = 'E';
  void (^block)() = ^{
    printf("%c
", e);   };   return block; }   void exampleE() {   eBlock block = exampleE_getBlock();   block(); }

A.常に正常に動作するB.ARCを使用する場合のみ正常に動作するC.ARCを使用しないと正常に動作しないD.永遠に正常に動作しない
 
 
解答例1 Aは正しい.この例は正常に動作します.exampleAを格納するスタックは、blockが実行を停止した後にのみ解放されるため、このBlockはシステムによってスタックに割り当てられても、私たち自身が手動でスタックに割り当てられても正常に実行できます.例2 Bは正しい.ARCを使用しない場合、このblockはNSStackBlockであり、exampleB_に割り当てられます.addBlockToArrayのスタックにあります.一方、exampleBで実行すると、スタックが空になったため、blockは有効ではありません.ARCを使用すると、ブロックはスタックに割り当てられ、自動的に解放されるNSMallocBlockの例3 Aとして正しくブロックは自分のループで変数をキャプチャしないため、実行時にstateを設定する必要はなく、NSGlobalBlockとしてコンパイルされます.スタックでもスタックでもなく、コードクリップの一部です.常に正常に動作します例4 Bは正しい.この例は例2と似ている.ARCを使わないと、blockはexampled_にgetBlockのスタックに作成します.そして、機能が戻るとすぐに失効します.しかし、この例では、このエラーは非常に明らかなので、コンパイラのコンパイルに失敗します.エラーメッセージ:error:returning block that lives on the local stack(エラー、返されたブロックはローカルのスタックにあります).例5 Bは正しいです.この例は例4と似ていますが、コンパイラがエラーを認識していない以外はコードがコンパイルされてクラッシュします.さらに悪いことに、この例は特別で、最適化をオフにすると正常に動作します.テストの際は注意が必要です.ARCを使用すると、ブロックは自動的に解放されるNSMAllocBlockとしてスタック上に正しく配置されます.結論この小さなテストは何の意味がありますか?ARCをずっと使うという意味です.ARCを使用すると、blockはほとんど正常に動作します.ARCを使用しない場合は、念のためblock=[[block copy]autorelease]を使用します.これにより、blockはスタックflameを明記するよりも有効期間が長くなります.これによりblockはNSMAllocBlockとしてスタックに強制的にコピーされます.しかし、もちろん簡単ではありません.アップルのドキュメントによると、BlockはARCモードでblockをスタックに渡してからしか動作しません.例えば、戻ってきたときだけです.Block Copyを再度呼び出す必要はありません.しかし、ブロックがスタックからarrayWithObjectsに渡されると、他のretainの方法がある場合は、[^{}copy]を使用する必要があります.しかし、あるLLVMのメンテナンス担当者は、コンパイラのバグだと考えていますが、現在は修復されています.しかし、Xcodeが今後リリースされる新しいバージョンでこの問題を解決するかどうかは、私にもわかりません.だから、アップルもそれをバグと見なして、後で新しいバージョンでこの問題を解決することを望んでいます.どうなるか見てみましょう.原文:http://blog.parse.com/2013/02/05/objective-c-blocks-quiz/