2012-02-10 19 views
4

私はブロックの機会を探る瞬間、10回以上リンゴのドキュメントを読んでいますが、ブログの例やコードではブロックの動作を理解できません。私は__block修飾子について知っています。だから、いくつかの私の例を見て、それがうまくいくかどうかを言う:ブロックと変数

1)働いていない。私はオブジェクトを変更したいので、__blockが必要です。自己(正しい?)を保持し、ブログで私は自分自身のサイクルを保持することによって怖がっています。それはありますか?

NSDictionary *result = nil; 
dispatch_async(queue, ^{ 
    result = [self sendRequest:apiRequest]; 
}); 

2)動作しません。私はdispatch_async(dispatch_get_main_queue()、^ {});の可変スコープについて理解していません。メインスレッド内のすべてのローカル変数を参照するか、メインスレッドとは別のブロックですが、メインスレッド内に出現しますか? dispatch_async(dispatch_get_main_queue()^ {})と同様です。 dispatch_async(queue、^ {})内のすべてのローカル変数をコピーします。セマフォをメインスレッドに切り替えます。

NSDictionary *result = nil; 
dispatch_async(queue, ^{ 
    NSDictionary *data = [self sendRequest:apiRequest]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     result=[data retain]; 
    }); 
}); 

3)ブログやスタンフォードのコースの例は、私が特にうまくいきます。なぜなら、彼らは働くからです。まず、彼らは記事やレッスンで自己のため__blockについて言及いけないので、私は、理解しない

- (void)viewWillAppear:(BOOL)animated 
{ 
    dispatch_queue_t downloadQueue = dispatch_queue_create(“image downloader”, NULL); 
    dispatch_async(downloadQueue, ^{ 
     NSData *imageData = [NSData dataWithContentsOfURL:networkURL]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      UIImage *image = [UIImage imageWithData:imageData]; 
      self.imageView.image = image; 
      self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height); 
    self.scrollView.contentSize = image.size; 
     }); 
    }); 
    dispatch_release(downloadQueue); 
} 

は、二本のコードは、変数を変更しますが、プロパティやコンパイラによって変数が割り当て可能アレントとプロパティが参照を変更することを誓うしません、値ではない。最終的には動作します。前もって感謝します。

答えて

2

1)はい、あなたは宣言する必要があるでしょう:

__block NSDictionary *results = nil; 

あなたはARCを使用している場合、それは自動的に保持し、結果オブジェクトを解放するの世話をする必要があります。 ARCを使用していない場合は、最初にretainを実行し、ブロックで最後に行うことはreleaseとしてください。

2)ブロックには、親のスコープで使用可能なすべての変数/オブジェクトの可視性が必要です。そのため、あるメソッドでは、そのメソッドとそのメソッドが属するオブジェクト(selfなど)のすべてのローカル変数を参照することができます。

3)これについてはあまり気にしないでください。変数は、関数/メソッドを終了すると消え去ります(となります)。selfの部分は実行されません。たぶんそれはそれと関係があります。

+0

おかげで、なぜ 'self.imageView.image =イメージん;第​​三exambleで'作業が、第一ニーズの 'result'は_block?違いはなんですか? – stworks

+0

私は推測しています。なぜなら、メソッドが完了すると(通常、ブロックが完了する前に)、 'result'が存在しなくなるからです。まだ必要であることを伝える必要があります。私は '__block'はそれを保持し、ブロックがそれを解放することを示していると思います。 – twilson

+1

私は 'self.imageView.image = image;'はインスタンス変数に直接アクセスしていないので動作すると思います。私が正しい場合、実際には[[self getImageView] setImage] = image; 'を実行しています。 – Frank

5

古い質問が、私は新しい読者のように感じる現在のものよりも、より正確な答えの恩恵を受ける可能性があります

1)resultはオブジェクトではなく、オブジェクト自体へのポインタです。そのポインタがブロック内に割り当てられているため、前もって__blockが必要です。ブロック外のポインタ変数が指し示すオブジェクトを変更することは問題ではない。

NSMutableDictionary* result = [NSMutableDictionary new]; 

[result setObject...]でブロック内のオブジェクトを変更しても問題ありません。それが3)の理由です:selfが指すオブジェクトの変数のみが変更されています。ポインタselfは割り当てられません。

ブロックが参照するオブジェクトのARCでの保持については、:

ARC with blocks and retain cycles

ARC, Blocks and Retain Cycles

blocks and ARC - copy or crash with release build (caused by optimization level)

関連する問題