ナビゲーション バーでビューを切り替えるときに、EXC_BAD_ACCESS エラーを発生させずに NSOperationQueue スレッドを安全に終了する方法
-
18-09-2019 - |
質問
UITableView を使用して文字列メッセージを表示し、NSOperationQueue を使用して、バックグラウンド スレッドでメッセージを取得するカスタマイズされた NSOperation を保持しています。1 つのメッセージが正常にフェッチされると、カスタマイズされた NSOperation はそれを表示するように UITableView コントローラーに通知します。
すべてのメッセージが読み込まれた後、ナビゲーション バーの戻るボタンをクリックして UITableView から他のビューに切り替えると、すべて問題ありません。ただし、メッセージの読み込み中に戻るボタンをクリックすると、EXC_BAD_ACCESS がスローされます。カスタマイズされたNSOperationがUITableViewコントローラーに通知しているときに例外が発生したことを確認しました performSelectorOnMainThread
方法。ビューが切り替わった後、ターゲットの UITableView コントローラーは無効ではないようですが、ナビゲーション コントローラーがビュー コントローラーのインスタンスを保持すると思います。この問題を解決する方法を教えていただけますか?ありがとう。
カスタマイズされた操作は、次のコードを使用して UITableView コントローラーで初期化されます。
StatusMessageLoadingOperation *operation = [[StatusMessageLoadingOperation alloc]
initWithData:person
messageArray:cachedStatusMessages
target:self
action:@selector(didFinishStatusMessages:)];
[operationQueue addOperation:operation];
[operation release];
カスタマイズされた NSOperation クラスは、次のコードで UITableView を更新します。
- (void)main{
for (int i = 0; i < [[person statusMessages] count]; i++) {
[target performSelectorOnMainThread:action withObject:messageArray waitUntilDone:NO];
}
}
解決
あなたの[operationQueue cancelAllOperations]
方法でviewWillDisappear
を呼び出して試したことがありますか?
他のヒント
ビューコントローラーをポップするとそのコントローラーの呼び出しが行われるため、 -dealloc
メソッドを使用している場合、キューの解放が早すぎる可能性があります。アプリケーションの他の部分が、存在しないキューまたはキュー内の操作にアクセスしようとしています。
私のおすすめは、 NSOperationQueue *myQueue
インスタンスをアプリケーションデリゲートに追加します。
アプリデリゲートを使用する -applicationDidFinishLaunching:
そして -dealloc
キューとその内容を初期化および解放するためのメソッド。
キューをビュー コントローラーから分離すると、ナビゲーション スタックからビュー コントローラーをポップオフしたときにキューが解放されなくなります。これと残りの操作は、アプリケーションの残りの部分で引き続き使用できるはずです。
キューにアクセスしやすくするには、次のマクロ定義を設定します。
#define UIAppDelegate ((MyAppDelegate *)[UIApplication sharedApplication].delegate)
次に、マクロを使用して次のようにキューにアクセスできます。例:
NSLog(@"%@", [[UIAppDelegate myQueue] operations]);
または、たとえば:
[[UIAppDelegate myQueue] addOperation:myOperation];