一連のURL呼び出し(WMSタイルのフェッチ)を実行する必要があります。LIFOスタックを使用したいので、最新のURL呼び出しが最も重要です。パンの5秒前に画面に表示されていたタイルではなく、今すぐ画面にタイルを表示したいと思います。
NSMutableArrayから独自のスタックを作成できますが、NSOperationQueueをLIFOスタックとして使用できるかどうか疑問に思っていますか?
一連のURL呼び出し(WMSタイルのフェッチ)を実行する必要があります。LIFOスタックを使用したいので、最新のURL呼び出しが最も重要です。パンの5秒前に画面に表示されていたタイルではなく、今すぐ画面にタイルを表示したいと思います。
NSMutableArrayから独自のスタックを作成できますが、NSOperationQueueをLIFOスタックとして使用できるかどうか疑問に思っていますか?
を使用して、操作キュー内の操作の優先順位を設定できます-[NSOperation setQueuePriority:]
。操作を追加するたびに、既存の操作の優先順位を再調整する必要がありますが、探しているもののようなものを実現できます。基本的に、古いものをすべて降格し、最新のものを最優先します。
NSOperationQueue
悲しいことに、sはその名前が示すように、スタックとしてではなく、キューとしてのみ使用できると思います。タスクの手動マーシャリングを大量に行う必要がないようにするには、おそらく最も簡単な方法は、キューを不変であり、コピーによって変更されているかのように扱うことです。例えば
- (NSOperationQueue *)addOperation:(NSOperation *)operation toHeadOfQueue:(NSOperationQueue *)queue
{
// suspending a queue prevents it from issuing new operations; it doesn't
// pause any already ongoing operations. So we do this to prevent a race
// condition as we copy operations from the queue
queue.suspended = YES;
// create a new queue
NSOperationQueue *mutatedQueue = [[NSOperationQueue alloc] init];
// add the new operation at the head
[mutatedQueue addOperation:operation];
// copy in all the preexisting operations that haven't yet started
for(NSOperation *operation in [queue operations])
{
if(!operation.isExecuting)
[mutatedQueue addOperation:operation];
}
// the caller should now ensure the original queue is disposed of...
}
/* ... elsewhere ... */
NSOperationQueue *newQueue = [self addOperation:newOperation toHeadOfQueue:operationQueue];
[operationQueue release];
operationQueue = newQueue;
現在、(古い操作キューで発生するように)まだ機能しているキューを解放しても、すべての操作がキャンセルされるわけではないようですが、これは文書化された動作ではないため、おそらく信頼できません。本当に安全にしたい場合は、key-valueoperationCount
が古いキューのプロパティを監視し、ゼロになったときに解放します。
あなたがまだ解決策を探しているかどうかはわかりませんが、同じ問題がしばらくの間私を悩ませてきたので、私は先に進んで、ここで操作スタックを実装しました:https ://github.com/cbrauchli/ CBOperationStack。私はそれを数百のダウンロード操作で使用しました、そしてそれはうまく持ちこたえました。
悲しいことに、いくつかのトリッキーな問題に遭遇せずにそれを行うことはできません。理由は次のとおりです。
重要操作を実行したり、操作キューに追加したりする前に、常に依存関係を構成する必要があります。後で追加された依存関係は、特定の操作オブジェクトの実行を妨げることはありません。(From:並行性プログラミングガイド:相互運用性の依存関係の構成)
この関連する質問を見てください。AFURLConnectionOperation'start'メソッドは、準備が整う前に呼び出され、その後は二度と呼び出されません。
NSOperationQueueの上にスタック/LIFO機能のきちんとした実装を見つけました。NSOperationQueueまたはNSOperationQueueLIFOサブクラスを拡張するカテゴリとして使用できます。
最も簡単な方法は、操作と処理するデータを分離することです。これにより、通常どおり操作をNSOperationQueueに追加してから、スタックまたはその他の必要なデータ構造からデータを取得できます。
var tasks: [MyTask]
...
func startOperation() {
myQueue.addOperation {
guard let task = tasks.last else {
return
}
tasks.removeLast()
task.perform()
}
}
さて、明らかに、タスクコレクションを同時に使用できるようにする必要があるかもしれませんが、NSOperationQueueの実行順序をハッキングするよりも、多くの既成のソリューションではるかに一般的な問題です。