NSOperationQueue快速完成所有任务3

时间:2021-12-12 17:35:51

I am trying to achieve NSOperationQueue finishing all tasks operation in swift 3. I create a below demo code and it is working according to my expectation.

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

Output :

输出:

BlockOperation1
0
1
2
3
4
5
BlockOperation2

But when I call a Web API with Alamofire in downloadArticle method output is different.

但是当我在下载文章中使用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
    }

Now output :

现在输出:

BlockOperation1
BlockOperation2
0
1
2
3
4
5

What i am doing wrong here ?

我在这做错了什么?

1 个解决方案

#1


8  

Your downloadArticle method is creating a block operation that completes immediately because it in turn performs an asynchronous operation.

您的downloadArticle方法正在创建一个立即完成的块操作,因为它反过来执行异步操作。

You need to prevent the block from reaching the end until the async fetch completes. Using a semaphore would be one solution.

在异步提取完成之前,您需要阻止阻止到达目的地。使用信号量将是一种解决方案。

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
}

The use of this semaphore ensure the operation doesn't actually complete until the network fetch is also complete.

使用此信号量可确保在网络提取完成之前,操作实际上不会完成。

You might also want to make your operation queue serial instead of concurrent to ensure you only allow one operation to run at a time. If this is what you want, then set the operation queue's maxConcurrentOperationCount to 1.

您可能还希望将操作队列设置为串行而不是并发,以确保一次只允许一个操作运行。如果这是你想要的,那么将操作队列的maxConcurrentOperationCount设置为1。

#1


8  

Your downloadArticle method is creating a block operation that completes immediately because it in turn performs an asynchronous operation.

您的downloadArticle方法正在创建一个立即完成的块操作,因为它反过来执行异步操作。

You need to prevent the block from reaching the end until the async fetch completes. Using a semaphore would be one solution.

在异步提取完成之前,您需要阻止阻止到达目的地。使用信号量将是一种解决方案。

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
}

The use of this semaphore ensure the operation doesn't actually complete until the network fetch is also complete.

使用此信号量可确保在网络提取完成之前,操作实际上不会完成。

You might also want to make your operation queue serial instead of concurrent to ensure you only allow one operation to run at a time. If this is what you want, then set the operation queue's maxConcurrentOperationCount to 1.

您可能还希望将操作队列设置为串行而不是并发,以确保一次只允许一个操作运行。如果这是你想要的,那么将操作队列的maxConcurrentOperationCount设置为1。