2016-06-22 1 views
0

NSOperationを使用していくつかのネットワークメソッドを実行し、その上に設定されたNSOperationQueueに操作を追加したいバックスレッド、私はNSOperationsがシリアル化されるようにしたい。NSOperationQueueとNSOperationを使用して、バックグラウンドでNSTimerを使用して定期的にシリアル化されたダウンロードタスクを呼び出す方法

NSOperationキューを作成する呼び出しは、NSTimerを使用して30秒ごとに定期的に呼び出されます。ここで

は、これまでに切り取らコードです:

NSTimer *timer; 
NSOperationQueue *bgQueue; 

- (void)startdDownloadLoop{ 

    if (![self.timer isValid]){ 

     self.bgQueue = [[NSOperationQueue alloc] init]; 
     self.timer = [NSTimer scheduledTimerWithTimeInterval:30.0 
                 target:self 
                selector:@selector(updateDB) 
                userInfo:nil 
                repeats:YES]; 

    } 

} 

- (void)updateDB{ 

    //  Next code was removed since si similar to the call `[self.bgQueue cancelAllOperations];`, as @robinkunde suggested 
    //  for (NSOperation *operation in [self.bgQueue operations]) { 
    //   if (operation.isExecuting) { 
    //    [operation cancel]; 
    //   } 
    //  } 

    [self.bgQueue cancelAllOperations]; 


    self.bgQueue = [[NSOperationQueue alloc] init]; 
    self.bgQueue.maxConcurrentOperationCount = 1; 

    NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadCars]; 
    }]; 

    NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadPartsForAllCars]; 
    }]; 

    NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadEachPathSpecs]; 
    }]; 

    [self.bgQueue addOperation:blockOp1]; 
    [self.bgQueue addOperation:blockOp2]; 
    [self.bgQueue addOperation:blockOp3]; 

} 

NetworkManagerの方法は、彼らがダウンロードし終えた後、彼らはDBに日付を保存してから使用してUIを更新することを、完了ハンドラでPOST/GETメソッドですお知らせ。

更新:混乱以来

、私は休閑など、コードに関する私の実際の質問を投稿するために考えた:

の1- NSOperationQueueの実行がシリアルになりますか?

2 - 私が[operation cancel]を呼び出すときに操作の実行を停止しますか?

3 - 私がcancelAllOperationsと呼んでいるときに再起動すると、現在の正しい方法であるNSOperationQueueがクリアされますか?

+0

おそらくあなたが望むことはしません。おそらくそれぞれの 'download ...'メソッドは非同期的に実行されます。そうであれば、ネットワーク操作がディスパッチされるとすぐにブロックが完了し、次のサブミットされたブロックは、最初のダウンロード操作がまだ完了していなくても実行を開始する。 dispatch_groupを使う方が良いでしょう。ポーリングではなく、バッテリーやネットワークトラフィックの点で高価なプッシュ通知を使うのが良いでしょう。 – Paulw11

+0

操作を取り消す限り、ブロックごとに 'isCancelled'プロパティと適切に作業を中止する。操作キューは操作を実際にキャンセルすることはできません。操作キューには、操作自体をキャンセルする必要があることを示すプロパティが設定されます。 http://stackoverflow.com/questions/8113268/how-to-cancel-nsblockoperationを参照してください – Paulw11

答えて

1

1)シリアル実行を確実にするために、キューのプロパティmaxConcurrentOperationCountを1に設定できます。

2)操作では、isCancelledプロパティのみが設定されます。この変更に対応し、キューから削除できるように完了状態に移行する必要があります。

具体的な例:NSBlockOperationは、すべての添付ブロックが返ってきたとみなされます。実際には、NetworkManagerへの呼び出しが同期しない限り、ブロックはすぐに戻り、操作は終了したとみなされ、キューは次の操作を開始します。最初のネットワーク操作が完了する前にキューが完了することは完全に可能です。一度に1つずつ実行したい場合は、これを行う方法ではありません。

同期ネットワーク操作を使用できますが、それでも無効にすることはできません。

は、この答えをチェックアウト:NSURLSession with NSBlockOperation and queues

3)これは2に関連しています)。 cancelAllOperationsにはすべての操作でisCancelledプロパティが設定されています。これらの操作が完了するまで、キューは引き続き存在します。同じプロパティで新しいキューを作成してもそれは変わりません。

+0

あなたのための@robinkundeありがとうございました応答私は余分なfor-loopを削除することに応じて私のコードを変更しますが、私の質問はどのようにすることができますまだ実行中のNSOperationを強制停止しますか? –

+0

私は自分の答えを更新しました。 – robinkunde

関連する問題