等到DispatchWorkItem完成

时间:2018-03-09 18:04:20

标签: ios swift multithreading grand-central-dispatch

我有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)
    }
    ...

但是我希望所有变量只能由主线程访问。

1 个答案:

答案 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")
}

Code from here