画面が適切に更新されず、ポップされたビューが表示されたままになっているが、明らかに割り当てが解除さ.navigationController popViewControllerAnimated:YES
れている場所から呼び出すと、奇妙な問題が発生します。NSOperation
sqlite
詳細: ローカルデータベースにアクセスするリスト ビューがあります。レコードをタップすると、そのレコードの詳細ビューが表示され、(メイン スレッドで) 非同期の NSOperation が開始され、XML バックエンド データベースをチェックして、そのレコードがまだデータベースで使用可能かどうかが確認されます。アーキテクチャ上の理由から、この操作はリスト ビューでは実行できません。詳細ビューで実行する必要があります。最後の同期以降にレコードが削除された場合、レコードが削除されたことをユーザーに通知popViewControllerAnimated
し、共有アプリのデリゲートで を呼び出します。理想的には、これにより現在の詳細ビューがポップされ、前のリスト ビューに戻ります。
エラー: 適切なビューが実際にはメモリにポップされていますが (割り当てが解除されています)、まだ画面に表示されています。ナビゲーション バーは空白ですが、「戻る」ボタンがあるべき場所をクリックすると、リスト ビューの前に開始画面に移動します。つまり、少なくともナビゲーション バーは本来あるべき場所を理解しています。タイトルまたは戻るボタンが正しく表示されない場合。主な問題は、詳細ビューがまだ表示されていて操作できるため、アプリケーションがクラッシュすることです。たとえば、詳細ビューにもデータが表示され、ユーザーがテーブルを下にスクロールすると、「メッセージが割り当て解除されたインスタンスに送信されましたUITableView
」という例外がスローされます。-[xAccountDetailController tableView:cellForRowAtIndexPath:]:
これにより、呼び出しによって詳細コントローラーの割り当てが適切に解除されたと思われますが、ビューコントローラーがナビゲーションコントローラーからポップされたとしてもpopViewControllerAnimated
、テーブルが実際に を呼び出す場合、明らかに何かがまだメモリに存在します。cellForRowAtIndexPath
詳細ビュー (バックエンドで削除されていないレコードの場合) で戻るボタンを手動で押すと、完全に機能します。
回避策: NSOperation に詳細ビュー コントローラーへの参照を渡すときに、popViewControllerAnimated
そのビューの navigationController プロパティから直接、および共有アプリ デリゲートから を呼び出そうとしました。また、2 つのビューをポップして、リスト ビューを navigationController に再プッシュしようとしましたが、ルート ビュー コントローラーとリスト ビュー コントローラーがナビゲーション バーに同時に存在するように見える (タイトルが互いに上書きされる) さらに厄介なインターフェイス効果が発生します。存在しないのではなく)。NSOperation に存在する詳細ビュー コントローラーへの参照を nil に設定しようとしましたが、何もしません。ポップする前に a を呼び出してみまし[detailView release]
たが、予想どおり、リリース前の保持カウントが 1 しかなかったため、ポップで失敗します。私'popToViewController
そしてpopToRootViewController
、何も機能していないようです。古いビューは常にそこにあり、ナビゲーション バーは何かを実行しているように見える唯一のインターフェイス要素であり、それでも正しく表示されません。ビューが表示されたまま(ポップなし)になってもかまわないので、テーブルのリロードも試みましたが、データをクリアしたいだけですが、何らかの理由でテーブルが reloadData しません。
考え: NSOperation を実行している operationQueue は問題の詳細ビューのプロパティであるため、詳細ビューの dealloc で cancelAllOperations を実行し、operationQueue への参照を nil に設定するようにしました。また、他のオブジェクトのそのビューへのすべての参照が nil に設定されていることを確認しようとしました。詳細ビューのボタンから直接呼び出すpopViewControllerAnimated
ことは完全に機能するため、ポップしたい詳細ビューのプロパティである NSOperationQueue で実行されている NSOperation からそのメソッドを呼び出しているという事実に違いありません。どこかの参照がそのビューを部分的に維持しているに違いありませんが、ポップが呼び出されたときにまだビューを参照しているものを見つけることができないようです。
ここに投稿するにはあまりにも多くの場所にコードが多すぎます。
何かご意見は?
長い質問で申し訳ありませんが、よろしくお願いします。
グレッグ
編集 1: 新しい UIViewController を使用して、NSOperation の外部でこの問題を簡単に再現できます。
メソッドでは、次のtableView:didSelectRowAtIndexPath
ように呼び出します。
xBaseViewController * vc = [[xBaseViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:vc animated:YES];
[vc performSelectorOnMainThread:@selector(popView) withObject:nil waitUntilDone:YES];
vc では、popView メソッド:
[self.navigationController popViewControllerAnimated:YES];
これは保持カウントや NSOperation とは関係ないと思います。この方法でビューをポップすることで根本的に間違ったことをしていますか?