【问题标题】:NSOperationQueue finishes all tasks swift 3NSOperationQueue 迅速完成所有任务 3
【发布时间】:2017-09-19 18:29:51
【问题描述】:

我正在尝试实现 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

我在这里做错了什么?

【问题讨论】:

  • 你没有做错什么。并发操作队列的输出是预期的。

标签: ios swift nsoperation nsoperationqueue


【解决方案1】:

您的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

【讨论】:

    猜你喜欢
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    相关资源
    最近更新 更多