1

画面が適切に更新されず、ポップされたビューが表示されたままになっているが、明らかに割り当てが解除さ.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 とは関係ないと思います。この方法でビューをポップすることで根本的に間違ったことをしていますか?

4

1 に答える 1

2

あなたの問題は、メイン スレッドではないスレッドで画面を更新しようとしていることです。iOS では、メイン スレッドで画面上で起こっていることのみを更新できます。

次のようなコードが必要です。

[self performSelectorOnMainThread:@selector(mymethod) withObject:nil waitUntilDone:YES modes:nil];

そして、それはただダンディに動作するはずです.

于 2010-09-13T12:37:43.523 に答える