NSOperationQueue 完成所有任务 swift 3
NSOperationQueue finishes all tasks swift 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
Output :
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
}
Now output :
BlockOperation1
BlockOperation2
0
1
2
3
4
5
我做错了什么?
您的 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
。
我正在尝试实现 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
但是当我在 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
}
Now output :
BlockOperation1
BlockOperation2
0
1
2
3
4
5
我做错了什么?
您的 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
。