Swift 在无止境的循环中等待,但用户每次都可以取消

Swift 在无止境的循环中等待,但用户每次都可以取消,swift,loops,user-interface,delay,delayed-job,Swift,Loops,User Interface,Delay,Delayed Job,在Swift 3中,我有一个循环,可以通过用户按下按钮来取消。在循环中进行了一些检查。检查后,任务可以休眠一分钟。但是当调用任务时 let delayQueue = DispatchQueue(label: "com.myApp.queue3", qos: .utility) let additionalTime: DispatchTimeInterval = .seconds(3) repeat { delayQueue.asyncAfter(deadline: .now() + a

在Swift 3中,我有一个循环,可以通过用户按下按钮来取消。在循环中进行了一些检查。检查后,任务可以休眠一分钟。但是当调用任务时

let delayQueue = DispatchQueue(label: "com.myApp.queue3", qos: .utility)
let additionalTime: DispatchTimeInterval = .seconds(3)

repeat {
    delayQueue.asyncAfter(deadline: .now() + additionalTime) { self.update() }
} while !self.stop
循环本身需要一直运行,等待用户 “停止”,表示用户单击了停止按钮。
这是在浪费CPU的能量吗?我怎样才能避免一直执行此循环?

您应该改用计时器

var timer: Timer?
let timeInterval: TimeInterval = 3

func didPressCancelButton() {
    timer?.invalidate()
}

func beginUpdates() {
    timer = Timer.scheduledTimer(
        timeInterval: timeInterval,
        target: self, 
        selector: #selector(self.update),
        userInfo: nil, 
        repeats: true
    );
}

func update() {
    print("Updated")
}

您可以将循环放在线程中并使其休眠,而不是使用外部循环延迟线程中的执行

import Foundation

class YourUpdatingClass {

    private let updateQueue: OperationQueue
    init() {
        updateQueue = OperationQueue()
        updateQueue.name = "com.myApp.queue3"
        updateQueue.qualityOfService = .utility
    }

    private var updateOperation: BlockOperation?

    @IBAction func startUpdating() {
        guard updateOperation == nil else {
            // In case if updating already started
            return
        }

        updateOperation = BlockOperation { [weak self] in
            while true {
                Thread.sleep(forTimeInterval: 3)
                self?.update()
            }
        }

        updateQueue.addOperation(updateOperation!) // we just created updateOperation, so we can use `!`, but use it with caution
    }

    @IBAction func stopUpdating() {
        updateOperation?.cancel()
        updateOperation = nil
    }

    private func update() {
        print("update") // Whatever your update does
    }

}
您的更新包含在永恒的while循环中,该循环每3秒小睡一次


停止是通过取消操作来管理的,而不是检查循环中的某些变量。

谢谢,这看起来很简单。一个问题:在上面的解决方案中,计时器正在调用主DispatchQueue上的任务?因为我没有得到在主队列中运行的对话框项的更新,所以我需要将其作为另一个队列启动,例如实用工具。
func update(){print(Thread.current)print(“Updated”)}
Output:{number=1,name=main}很好。如果它变得更复杂,我将使用这个解决方案。这是更普遍的解决办法。谢谢!