我必须执行一些操作,直到更改启动它们的开关为止。我尝试将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()
}
}
答案 0 :(得分:-1)
您需要在类顶部声明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时只是为了举例说明。