Swift 使用OperationQueue时更新UI
我有一个操作队列设置,如下所示:Swift 使用OperationQueue时更新UI,swift,blockoperation,operationqueue,Swift,Blockoperation,Operationqueue,我有一个操作队列设置,如下所示: let queue = OperationQueue() queue.name = "com.company.myQueue" queue.qualityOfService = .userInitiated queue.maxConcurrentOperationCount = 64 ... var current = 0 var totalCount = someArray.count for i in someArray { ... let op =
let queue = OperationQueue()
queue.name = "com.company.myQueue"
queue.qualityOfService = .userInitiated
queue.maxConcurrentOperationCount = 64
...
var current = 0
var totalCount = someArray.count
for i in someArray {
...
let op = BlockOperation {
... // do some database queries
current += 1
}
op.completionBlock = {
DispatchQueue.main.async {
let nData: [String: CGFloat] = ["value": CGFloat(current/totalCount)]
NotificationCenter.default.post(name:Notification.Name(rawValue: "update"), object: nil, userInfo: nData)
}
queue.addOperation(op)
}
在我的ViewController
中,我监听通知并用百分比更新UILabel
。问题是虽然我没有得到任何中间值。。。所有操作完成后,它从0
直接跳到100
我做错了什么
谢谢您可以直接在op.completionBlock中移动通知发送功能(无需在主线程中调度) 编辑(评论):
let queue=OperationQueue()
queue.name=“com.company.myQueue”
queue.qualityOfService=.userInitiated
queue.maxConcurrentOperationCount=64
让数组=[“”,“”,“”,“”,“”,“”,“”,]
无功电流=0
var totalCount=array.count
用于数组中的uu{
设op=BlockOperation{current+=1;print(current)}
op.completionBlock={
DispatchQueue.main.async{
NotificationCenter.default.post(名称:Notification.name(rawValue:“update”),对象:nil,用户信息:[“value”:CGFloat(当前/totalCount)])
}
}
queue.addOperation(op)
}
NotificationCenter.default.addObserver(forName:Notification.Name(rawValue:“update”),对象:nil,队列:nil){(Notification)in
打印(notification.userInfo)
}
编辑2(评论):
在除以它们之前,您应该通过浮动铸造电流和totalCount来确定百分比
CGFloat(当前)/CGFloat(总计数)
'''
问题是CGFloat(当前/总计数)
。这将首先进行整数运算,然后将其转换为浮点。您应该将其翻转到CGFloat(当前)/CGFloat(总计数)
不更改结果。如果:您的数组大于1个条目?它有大约6000个元素,在通知发送调用的同一位置打印(当前/总计数)
:只调用一次?每个元素不调用,只声明0.0已完成
,0.0完成
-然后最后一个条目是1.0完成
不相关,但我可能建议扩展通知。Name{static let update=Notification.Name(rawValue:“update”)}
。然后您可以执行类似于NotificationCenter.default.post(名称:.update,对象:nil,用户信息:nData)
。我建议不要将maxConcurrentOperation
计数设为64,因为这样做很容易耗尽有限数量的工作线程。你一般应该保持在64岁以下。