Swift GCD工作项调度队列取消

我必须执行一些操作,直到更改启动它们的开关为止。我尝试将GCD与工作项队列一起使用,认为异步操作将允许用户更改开关并因此停止操作。代码运行时,它永远不会看到甚至触发开关更改。这是我的代码。知道我在做什么错吗?

@IBaction func trailerScanSwitchChange(_ sender: Any) {

    let model = Model()     //Instantiate the Model
    gScan = trailerScanSwitch.isOn
    //Set up work iten to read and parse data
    let work1 = DispatchWorkItem {
      while (gScan && gConnected){
        model.parseValues()
        print ("parsing values")
        if gScan == false || gConnected == false{
          break
        }
        model.convertVoltsToLights()
        self.updateLights()
        print ("updating Lights")
        if gScan == false || gConnected == false{
          break
        }
      }
    }
    if trailerScanSwitch.isOn == true{
      print ("Scanning")
      //perform on the current thread
      work1.perform()
      //perpform on the global queue
      DispatchQueue.global(qos: .background).async(execute: work1)  // concurrent actions
      return
    }
    else {     //Stop reading and displaying
      gScan = false
      work1.cancel()
    }
}
fajkasjifise 回答:Swift GCD工作项调度队列取消

您需要在类顶部声明DispatchWorkItem变量。在代码中,一旦编译器无法正常工作,变量1将变得不可访问。每次更改开关时,都会初始化一个新的DispatchWorkItem变量。请仔细阅读下面的示例,以正确使用DispatchWorkItem和停止/恢复功能

    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var label: UILabel!
    var isStart = false
    var work: DispatchWorkItem!

    private func getCurrentTime() -> DispatchWorkItem {

        work = DispatchWorkItem { [weak self] in

            while true {
                if (self?.work.isCancelled)!{break}
                let date = Date()
                let component = Calendar.current.dateComponents([.second],from: date)
                DispatchQueue.main.async {
                    self?.label.text = "\(component.second!)"
                }

            }

        }

        return work
    }

    @IBAction func btnPressed() {

        isStart = !isStart
        button.setTitle(isStart ? "Stop" : "Start",for: .normal)

        let workItem = getCurrentTime()
        let globalQueue = DispatchQueue.global(qos: .background)
        if isStart {
            globalQueue.async(execute: workItem)
        } else {
            workItem.cancel()
        }

    }

此示例将在标签中显示当前时间秒值。我使用true时只是为了举例说明。

本文链接:https://www.f2er.com/3010754.html

大家都在问