私のような状況で非同期ブロックを使用する際のベスト プラクティスについて質問があります。
たとえば、2 つのコントローラーがあります (コントローラー 1 とコントローラー 2 とします)。
controller1 内に controller2 をプッシュしています。
controller2 * c = [[controller2 alloc] init];
[self.navigationController pushViewController:c animated:YES];
[c release];
controller2 にはインスタンス変数があります。
@interface controller2 : UITableViewController{
UIImageView * imageView;
}
それを割り当てて解放します。
- (id)init{
...
imageView = [[UIImageView alloc] init];
...
}
- (void)dealloc{
[imageView release];
[super dealloc];
}
controller2 は、この imageView のイメージをダウンロードします。
- (void)viewDidLoad{
...
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:
^(NSURLResponse *response, NSData *data, NSError *error) {
UIImage * image = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] scale]];
imageView.image = image;
[image release];
}];
}
明らかに、ユーザーはナビゲーション バーの上部にある [戻る] ボタンを押すことができ、controller2 のオブジェクトはこの imageView で解放されます。
状況:
ダウンロードが開始されます。
コントローラーがポップされました (ユーザーが「戻る」ボタンを押しました)
ダウンロード終了、imageView.image=画像が原因(?) EXC_BAD_ACCESS(imageViewが解放されているため)
では、コードでクールにするにはどうすればよいでしょうか? ブロック好き!NSURLConnection デリゲートと比較して、非常に楽しく、少ないコード/クラスです。
ブロックはおそらくインスタンス変数を保持していますか? ( :OOO )
ブロックの前にインスタンス変数を保持し、ブロックで解放する必要がありますか? (それはばかげていると思います)
では、そのようなブロックを使用する際のベストプラクティスは何ですか? コードを改善するために、このような状況でブロックを使用しないでください。
ps: 私はこれをしようとしました: NSOperationQueue をインスタンス変数として作成し、dealloc のすべてのタスクを停止します..しかし、それはこのブロックの利点を殺します:(その場合、デリゲートで私のダウンローダークラスを使用する方が良いです;(とにかく多すぎるコード。
pps: コントローラーをポップしたらダウンロードを停止する必要があることはわかっています。しかし、私はそれについてではありません。ユーザーがこのコントローラーを離れたとしても、何らかのタスク (たとえば、ビデオの変換など、「重い」バックグラウンド スレッド) を実行する必要がありますが、インスタンス変数が有効な場合はいくつかのインスタンス変数を使用します。
ありがとうございました