2016-06-14 5 views
0

からcancelAllOperationsを呼び出し、pleaesは私と一緒にクマ:私はのように明確に可能な限りこれを説明することを試みてきたように、私は次のような状況に苦しんだネストされたNSOperations

私はのサブクラスであるクラスCoummintyOperationを持っていますGroupOperation。 CommuityOperationが呼び出され、NSOperationQueueに追加されます。 CommunityOperationは、GroupOperationのサブクラスでもあるNSOperationsを一斉に呼び出すと、その中でNSoperationsを呼び出しています。 CommunityOperationクラスのGroupOperationsの依存関係を追加しました。 私が扱っている問題は、ネストされた操作が失敗した場合です。私はCommunityOperationsクラスのすべてのNSOperationsをキャンセルする必要がありますが、cancelOllOperationsメソッドを呼び出すためにCommunityOperationが追加されたoperationQueueにアクセスできません。

誰でもこのメソッドを呼び出す方法を説明し、このクラスのすべての操作(したがってすべての入れ子にされた操作)をキャンセルして、エラーメッセージを表示することができます。事前

おかげでここに私の問題を説明するためのいくつかのサンプルコードです:で操作を入れ子になった CommunityOperationが別のクラスからoperationQueueに入れます(含まれていない)

public class CommunityOperation: GroupOperation { 

    var updateOperation: UpdateOperation! 
    var menuOperation: MenuOperation! 
    var coreDataSaveOperation: CoreDataSaveOperation! 

    var hasErrors = false 

    public init() { 

     super.init(operations: []) 

     updateOperation = UpdateOperation() 
     menuOperation = MenuOperation() 
     coreDataSaveOperation = CoreDataSaveOperation() 
     coreDataSaveOperation.addDependencies([updateOperation, menuOperation]) 

     self.addOperation(updateOperation) 
     self.addOperation(menuOperation) 
     self.addOperation(coreDataSaveOperation) 
    } 
} 

MenuOperationクラス、同様に:

class UpdateMenuOperation: GroupOperation { 

    let downloadGroupsOperation: DownloadGroupsOperation 
    let downloadMembersOperation: DownloadMembersOperation 

    init() { 
      downloadGroupsOperation = DownloadGroupsOperation() 
      downloadMembersOperation = DownloadMembersOperation(]) 

      super.init(operations: [downloadGroupsOperation, 
       downloadMembersOperation 
       ]) 
     } 
} 

DownloadGroupOperationクラスは再びGroupOperationのサブクラスです。これは、2つの事業を展開しています - データ解析するデータをダウンロードする第一及び第二:最後に

class DownloadTopGroupsOperation: GroupOperation { 
    let downloadOperation: DownloadOperation 
    let importTopGroupsOperation: ImportOperation 

    init() { 
     downloadOperation = DownloadOperation() 
     importOperation = ImportOperation() 
     importOperation.addDependency(downloadOperation) 
     importOperation.addCondition(NoCancelledDependencies()) 

     super.init(operations: [downloadOperation, importOperation]) 
    } 
} 

そして(やれやれ)DownloadOperationクラスはNSURLSessionと方法downloadTaskWithURLを使用していますが、それは私が欲しいこのメソッドの完了ハンドラ内ですエラーが返された場合、メインオペレーションキューのcancelAllOperationsを呼び出す:

+0

ソースコードが役立ちます。あなたは何をしているのか簡単な例をまとめることができますか? – Dominic

+0

@Dominicどのような提案ですか? – mrcurious

答えて

0

少し違う方法で動作するはずです。私はNSOperation実行の最後までGroupOperationからisCancelledを確認したいと思います。操作がキャンセルされた場合は、現在のGroupOperationなどをキャンセルします。最後に、CommunityOperationもキャンセルする必要があります。ここで

は、提案されたソリューションの大まかな実装です:

extension GroupOperation { 

    func addCancellationObservers() { 
     self.operations.forEach() { $0.willCancelObservers.append() { [unowned self] operation, errors in 
      self.cancel() // cancel the group operation. will force it to cancel all child operations 
      } 
     } 
    } 

} 

次に、あなたが持っている各グループ事業のinit方法からaddCancellationObserversを呼び出します。

+0

あなたは、私があなたの言っていることに従わない例を挙げてください。私はコードで自分の質問を更新しました。 – mrcurious

+0

GroupOperationsクラスに操作配列変数がありません – mrcurious

+0

https://github.com/danthorpe/Operationsのような独自の 'GroupOperations'またはカスタムソリューションを使用していますか? – sgl0v

0

Appleのサンプルコード(またはそのプロジェクトの進化であるhttps://github.com/danthorpe/Operations)を使用している場合は、依存関係のある操作に条件を付けることでこれを並べ替えることができます。ここで

がここで何が起こっているのかを説明するために、あなたのトップレベルGroupOperation

init() { 

    updateOperation = UpdateOperation() 
    menuOperation = MenuOperation() 
    coreDataSaveOperation = CoreDataSaveOperation() 
    coreDataSaveOperation.addDependencies([updateOperation, menuOperation]) 

    // Attach a condition to ensure that all dependencies succeeded 
    coreDataSaveOperation.addCondition(NoFailedDependenciesCondition()) 

    super.init(operations: [updateOperation, menuOperation, coreDataSaveOperation]) 
} 

の初期化です... NSOperationは「失敗」の概念がありません。操作は常に「終了」しますが、正常に終了したか失敗したかは、NSOperationの依存関係の動作には影響しません。

つまり、これらの依存関係が成功したかどうかにかかわらず、すべての依存関係が終了すると、操作は準備完了になります。これは、「成功」と「失敗」がサブクラスで定義する必要があるためです。 OperationNSOperationサブクラス)は、エラーなしで終了して成功を定義します。

これに対処するには、依存関係が失われていない条件を追加します。オペレーションでは、この状態が明確になるように名前が変更されました。しかし、コンセプトはAppleのサンプルコードにもあります。

+0

@DaneilThorpeその説明をありがとうございます。私はあなたが上で述べたことを理解しましたが、あなたのパッティングはとても簡潔に役立ちます。基本的に私の現在の解決策は、私の操作の 'operationDidFinish:WithErrors'メソッドにあります。エラーが発生したら、NSNotifiicationsを使って操作キューを作成したクラスの' operationQueue.cancelAllOperations() 'メソッドを呼び出していますエレガントな解決策ではありませんが、うまくいくようです)。 – mrcurious

+0

答えの2番目の部分に関しては、依存関係が失敗した場合にキューの後続操作がすべてキャンセルされるように、追加する場所と追加する場所が明確ではありません。あなたはそれにいくつかの光を当てることができますか? (私はあなたのOperationsプロジェクトをダウンロードしました)ありがとう – mrcurious

+0

@ Daniel.Thorpe cancelObserverのためにネストされた操作(例えばDownloadOperation)の1つがキャンセルされた場合、メインクラスから発生したすべての操作をどのように取り消しますか? – mrcurious

関連する問題