2017-04-22 17 views
3

私はNSOperationQueueをすべてのタスクの操作を迅速に完了するために努力しています。私は以下のデモコードを作成し、私の期待通りに動作します。NSOperationQueueはすべてのタスクを完了します。swift 3

func downloadTopStroiesDetails(){ 
    let operationQueue: OperationQueue = OperationQueue() 
    let operation1 = BlockOperation() { 
     print("BlockOperation1") 
     for id in 0...5{ 
      operationQueue.addOperation(downloadArticle(index: id)) 
     } 
     let operation2 = BlockOperation() { 
      print("BlockOperation2") 
     } 
     operationQueue.addOperation(operation2) 
    } 
    operationQueue.addOperation(operation1) 
} 

func downloadArticle(index:Int) -> Operation { 
    let operation: Operation = BlockOperation {() -> Void in 
     print(index) 
    } 
    return operation 
} 
downloadTopStroiesDetails() // start calling 

出力:

BlockOperation1 
0 
1 
2 
3 
4 
5 
BlockOperation2 

しかし、私はdownloadArticleメソッドの出力にAlamofireでのWeb APIを呼び出すときに異なっています。今

func downloadArticle(index:Int) -> Operation { 
     let operation = BlockOperation(block: { 
      RequestManager.networkManager.fetchFromNetworkwithID(articleid: index) { (response:Any ,sucess:Bool) in 
       if sucess{ 
         print(index) 
        //let art = article.init(json:(response as? json)!)! 
        // self.saveDataIntoCoreData(data: art) 
        //self.all_TopArticle.append(art) 
       } 
      }; 
     }) 
     return operation 
    } 

出力:私はここで何が問題を

BlockOperation1 
BlockOperation2 
0 
1 
2 
3 
4 
5 

をやっていますか?

+1

あなたは間違ったことはしていません。同時出力キューには出力が必要です。 – rmaddy

答えて

7

downloadArticleメソッドは、非同期操作を順番に実行するため、すぐに完了するブロック操作を作成しています。

非同期フェッチが完了するまで、ブロックが最後まで到達しないようにする必要があります。セマフォを使用することが1つの解決策になります。

func downloadArticle(index:Int) -> Operation { 
    let operation = BlockOperation(block: { 
     let semaphore = DispatchSemaphore(value: 0) 
     RequestManager.networkManager.fetchFromNetworkwithID(articleid: index) { (response:Any ,sucess:Bool) in 
      if sucess{ 
        print(index) 
       //let art = article.init(json:(response as? json)!)! 
       // self.saveDataIntoCoreData(data: art) 
       //self.all_TopArticle.append(art) 
      } 
      semaphore.signal() 
     }; 
     semaphore.wait() 
    }) 
    return operation 
} 

このセマフォを使用すると、ネットワークフェッチも完了するまで実際には完了しないことが保証されます。

一度に1つの操作のみを実行できるように、操作キューを並行ではなくシリアルにすることもできます。これが必要な場合は、操作キューのmaxConcurrentOperationCount1に設定します。

関連する問題