1

問題

  • NSOperationQueueという名前がありますlogEntryGeneratorQueue
  • キューのすべての操作が完了するまで待ちたい

私が使用する場合:

[logEntryGeneratorQueue waitUntilAllOperationsAreFinished];

キューに追加するスレッドがバックグラウンド自体にある場合は、正常に機能します。

ただし、単体テストでこのコードを実行している場合は、メインスレッドで実行されます。それで私はこの「解決策」を思いつきました、それは私が本当に好きではありません:

if ([NSThread isMainThread]) {
    while ([[logEntryGeneratorQueue operations] count] > 0) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    }
} else {
    [logEntryGeneratorQueue waitUntilAllOperationsAreFinished];
}

これは常に理想的とは言えませんでしたが、10.5では常に正常に機能していました。ただし、プロジェクトを10.6 SDKを使用するようにアップグレードしたため、これが機能しなくなりました。

あるテストでは、テストが完了する前に実際にテストを終了しました。理由はわかりません。10.6ではNSOperationQueuesの動作が異なっていたのと関係があると思いますが、現在はGCDを使用しています。

私が試したこと

runUntilDateをsleepに置き換えてみました。これは、私が思ったように、すべてのテストがここに到達すると永久に一時停止することを意味します。

私の質問

NSOperationQueueがメインスレッドで終了するのを待つより良い方法はありますか?そうでない場合、どうすればこのコードを10.6で動作させることができますか?

4

4 に答える 4

2

ソリューション

mergeChangesFromContextDidSaveNotificationメインスレッドでキューが終了するのを待っている間にメインスレッドを呼び出していたため、コードが永遠のループにあることに気付きました。また、マージの変更は後に呼び出されたためwaitUntilAllOperationsAreFinished、実行されませんでした。

答えは、NSOperationQueuesを実行する場所を変更することだと思います。メインスレッドでコアデータを処理するNSOperationQueueを実行するべきではありません。とにかく、パフォーマンス上の理由から、メインスレッドでこの集中的な処理を実際に実行するべきではありません。

于 2010-09-10T12:15:45.133 に答える
1

waitUntilAllOperationsAreFinishedどのスレッドから呼び出されても、10.6では期待どおりに機能するはずです。10.6の操作キューは実行ループを使用しなくなったため、ループをブロックせずに実行しても意味がありません。waitUntilAllOperationsAreFinished=とだけ呼ぼうとしましたか

于 2010-09-01T15:58:41.003 に答える
1

Maxに同意します:-waitUntilAllOperationsAreFinishedが機能するはずです。キューは一時停止されていますか?

于 2010-09-01T16:53:25.197 に答える
0

私見では、メインアプリスレッドをキャリアとして使用して操作の1つ(またはすべて)が進行している場合、waitUntilAllOperationsAreFinishedがハングする可能性を考慮する必要があります。例:nsoperationは同時ではなく、アニメーションと自身の状態の更新にglkview自動更新ループを使用し、メインスレッドが機能する機会がある場合にのみ操作が実行されます(操作は終了とマークされます)。しかし、これらの操作の終了を待つことでブロックされているため、それはできません。

于 2011-12-30T22:52:50.917 に答える