WWDC 2010 のプレゼンテーションをいくつか見ました。また、ブロックと同時実行性に関するドキュメントのほとんどを読みました。また、Grand Central Dispatch でのシリアル キューでのブロックの使用に関していくつか質問があります。スクロールビューと画像情報の辞書 (画像への URL など) を持つ iOS 4 プロジェクトがあります。GCD とブロックを使用して画像をダウンロードし、スクロールビューに配置して、メイン スレッドをブロックしないようにしたいと考えています。動作するように見える次のコードを書きました。
for (NSDictionary* dict in images)
{
dispatch_async(image_queue, ^{
NSString* urlString = [dict objectForKey:@"url"];
NSURL* url = [NSURL URLWithString:urlString];
NSData* imageData = [[NSData alloc] initWithContentsOfURL:url];
UIImage* image = [UIImage imageWithData:imageData];
UIImageView* imageView = // initialize imageView with image;
dispatch_async(dispatch_get_main_queue(), ^{
[self.scrollView addSubview:imageView];
});
[imageData release];
});
}
2 つの質問があります。
同時実行ガイドによると、非スカラー型である囲みスコープから変数をキャプチャするべきではありません - 私のコードでは、NSDictionary* オブジェクトである dict をキャプチャします。キャプチャが許可されていない場合、どのようにコードを記述すればよいですか? ブロックは、実際に使用されている外側のスコープから変数のみをキャプチャしますか?
すべての画像がシリアル ディスパッチ キューを介してフェッチされる前に、現在の ViewController を離れるとどうなりますか? それらを作成したViewControllerがなくなったことを彼らが認識しているとは思わないので、メインスレッドのスクロールビューに画像ビューを挿入する完了ハンドラーを実行するとどうなりますか? それはエラーを引き起こしますか、それとも何ですか?また、ViewController が消えたときに、シリアル キューの残りの操作をキャンセルするにはどうすればよいですか?
よろしくお願いします、