2017-04-22 94 views
3

所有的任务,我想实现NSOperationQueue完成在迅速3.所有任务操作创建一个下面的演示代码,它是根据我的意料工作。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 

但是,当我打电话与Alamofire一个Web API中downloadArticle方法的输出是不同的。

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方法是创建完成立即因为它反过来一个块操作执行异步操作。

您需要防止块到达终点,直到异步读取完成。使用信号量将是一个解决方案。

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 
} 

使用这种信号灯的保证手术实际上不完整的,直到网络获取也完成了。

您也可能想使你的操作队列串行而不是并行,以确保您只允许一个操作同时运行。如果这是您想要的,则将操作队列的maxConcurrentOperationCount设置为1