如何在后台线程上每秒执行一个方法,以免影响应用程序的性能

Jam*_*aja 1 timer background-thread swift

我试图每 30 秒访问一次我的数据库,但是,每当该方法执行时,我都可以清楚地看到应用程序的性能下降。

到目前为止,这是我当前的代码:

var timer = Timer()

override func viewDidLoad() {
    super.viewDidLoad()
    scheduledTimerWithTimeInterval()

}

func scheduledTimerWithTimeInterval(){
    timer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(self.updateCounting), userInfo: nil, repeats: true)
}

@objc func updateCounting(){
    getDatabaseInfo()
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试做同样的事情,但我想在后台线程上执行 getDatabaseInfo() 方法,这样应用程序的性能就不会受到影响。

iel*_*ani 5

使用 Grand Central Dispatch :

DispatchQueue.global(qos: .background).async {
    getDatabaseInfo()
}
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,获取数据库信息后所需的任何 UI 更新都应该在“主”线程内运行,如 Nikx 的回答所示。 (3认同)

Rob*_*Rob 5

您可以使用以下命令直接在后台队列上运行计时器DispatchSourceTimer

private var timer: DispatchSourceTimer?

func startTimer() {
    let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".timer")
    timer = DispatchSource.makeTimerSource(queue: queue)
    timer!.schedule(deadline: .now(), repeating: .seconds(1))
    timer!.setEventHandler { [weak self] in
        // do whatever stuff you want on the background queue here here

        getDatabaseInfo()

        DispatchQueue.main.async {
            // update your model objects and/or UI here
        }
    }
    timer!.resume()
}

func stopTimer() {
    timer?.cancel()
    timer = nil
}
Run Code Online (Sandbox Code Playgroud)

使用Timer,您可以在主队列的运行循环上安排它,然后让它将任务分派到后台队列,然后将 UI/模型更新分派回主队列。使用分派计时器,就像上面一样,绕过第一步,直接在 GCD 后台队列上运行计时器。