Pages

2011年11月25日金曜日

iOS5とNSOperation

NSOperationQueueとNSOperationとNSURLConnectionを使って非同期に画像やデータをダウンロードするという処理については、いろいろなところで紹介されていたりして結構メジャーな処理の一つだと思います。

御多分に漏れず私もこの手法の常習者のひとりであります。
この処理を使うアプリもいくつか開発した経験があります。

この処理ではNSOperationのサブクラスを作って各メソッドをオーバーライドするわけですが、cancelの中では、だいたい下のコードのようにプロパティを書き換えるのが普通じゃないでしょうか?

- (void)cancel {
  .....
  [self setValue:[NSNumber numberWithBool:YES] forKey:@"isFinished"];
  .....
}


ところが、これ、iOS5では[MyOperation isFinished = YES without being started by the queue it is in]なんてメッセージを吐きよる。

つまりは、startメソッドが実行されていないのにisFinishedをYESに設定するとは何事だ!と怒られてしまったわけです。iOS4までではこんなことで怒られることはありませんでした。まぁ、そう言われればそうやなって気もしないではないですが・・・

特に、[queue cancelAllOperations]とかを実行して大量の非同期オペレーションをキャンセルする場合なんかは大量にこのメッセージが出ます。しかも、[An instance 0xxxxxxxxx of class MyOperation is being deallocated while key value observers are still registered with it]とかいうメッセージも吐きだされて、これが直接的に関係しているかどうかは不明ですがアプリが落ちてしまうこともしばしば。

ではメッセージを回避しようということで、cancelメソッドの中を以下のように書きえてみました。



はい。メッセージは吐きだされなくなりましたが、今度はNSOperationがNSOperationQueueから削除されずに残り続ける結果に。

う~ん。どうしたものか。正しいお作法が見つかるまでは、とりあえず自作の疑似キューを作成して非同期通信キューの処理を実現することにしました。

0 コメント:

コメントを投稿