我有DispatchWorkItem
获取一些信息,我有一个显示信息的按钮。工人看起来像这样:
worker = DispatchWorkItem {
let info = getInfo()
DispatchQueue.main.async {
self.setInfo(info)
}
}
on viewDidLoad
我将worker添加到全局队列
DispatchQueue.global().asyncAfter(deadline: .now() + 0.35, execute: worker!)
当用户点击按钮时,我需要阻止执行,直到工人完成执行。
@IBAction func readInfo(_ sender: UIButton) {
// WAIT UNTIL THE WORKER HAS FINISHED EXECUTION
...
我设法让工人看起来像这样:
worker = DispatchWorkItem {
let info = getInfo()
self.setInfo(info)
}
并在用户点击按钮后检查信息是否每隔200毫秒设置一次:
@IBAction func readInfo(_ sender: UIButton) {
while(info == nil){
usleep(2000)
}
...
但是我希望所有变量只能由主线程访问。
答案 0 :(得分:1)
说实话,我不清楚你想要什么,但使用usleep(2000)
这样的东西是不恰当的。
所以,有一个可能的解决方案,但它是一般的,您可能需要根据需要进行修改。
let group = DispatchGroup()
var info: Info?
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().asyncAfter(deadline: .now() + 0.35) { [weak self] in
self?.getInfo()
}
}
func getInfo() {
group.enter()
asyncFunc()
group.notify(queue: .main) { [weak self] in
self?.setInfo(self?.info)
}
}
func asyncFunc() {
..... { [weak self] info in
self?.info = info
self?.group.leave()
}
}
如果要在加载某些内容时禁用用户交互,最好显示渐进式加载程序,但不要只是冻结应用程序。如果使用加载程序,用户将理解应用程序未被冻结。
有一个将DispatchWorkItem与DispatchGroup一起使用的示例:
let dispatchWorkItem = DispatchWorkItem{
print("work item start")
sleep(1)
print("work item end")
}
let dg = DispatchGroup()
//submiy work items to the group
let dispatchQueue = DispatchQueue(label: "custom dq")
dispatchQueue.async(group: dg) {
print("block start")
sleep(2)
print("block end")
}
DispatchQueue.global().async(group: dg, execute: dispatchWorkItem)
//print message when all blocks in the group finish
dg.notify(queue: DispatchQueue.global()) {
print("dispatch group over")
}