2012-01-24 8 views
0

NSOperationをキャンセルすると(ユーザーがボタンを押したとき)、キャンセルメソッドがメインスレッドから呼び出されますが、操作が別のスレッドで実行されていることは明らかです。 したがって、_isExecutingと_isFinishedを変更したときの競合状態を回避するために、キャンセル(または少なくともロジック)をNSOperationと同じスレッドから呼び出す必要があります。それとは別に、ユーザーがファイルを取り消すと、いくつかのファイルが削除され、時間がかかります。キャンセルはメインスレッドから呼び出されるため、すべてのアプリがしばらく応答しなくなりますが、これは醜いことです。操作と同じスレッドでNSOperationをキャンセルするにはどうすればよいですか?

現在のNSOperationと同じスレッドでキャンセルコードを実行するにはどうすればよいですか?

Iが(私はASIHTTPRequestで見たものと同様)、この中にキャンセルしようとした:

if (_operationThread) { 
    [self performSelector:@selector(cancelOnRequestThread) onThread:_operationThread withObject:nil waitUntilDone:NO]; 
} else { 
    [self cancelOnRequestThread]; 
} 

そして_operationThreadを使用して起動方法でsettedさ: _operationThread = [NSThread currentThread]。

しかし、動作しません。

アイデアやご提案はありますか?

注:私は同時操作を使用しているので、mainの代わりにstartを使用します。

ありがとうございました。 Ricardo。

答えて

4

メインスレッドからNSOperationでキャンセルを呼び出すのは問題ありません。 cancelメソッドはスレッドセーフです。

キャンセルメソッド自体が何もしてはいけないので、メインスレッドでブロックされるべきではありません。ファイルの削除などの操作のキャンセルメソッドをオーバーライドした場合、間違った方法です。 cancelメソッドをオーバーライドするのではなく、isCancelledメソッドを操作のメインメソッド内の通常の点(タイトループ内など)でチェックしてから、早くmainから戻ると、isCancelledメソッドはYESを返します。スレッドを実行の残りの部分として使用します。

これはすでに実装していて、まだパフォーマンスに問題がある場合は、操作が実際にバックグラウンドスレッドで実行されていない可能性がありますか?たとえば、[NSOperationQueue mainQueue]によって返されたキューに追加した場合、それは実際にはメインアプリケーションスレッドで実行されています。

関連する問題