如何停止backgroundUpdateTask?

How to stop backgroundUpdateTask?

这是我在用户关闭应用程序时在后台执行的代码,但这是奇怪的行为,在执行 endBackgroundUpdateTask() 方法后,DispatchQueue 仍然没有停止...

我收到通知了。

我做错了什么?

你可以拿这段代码自己试试,真的很奇怪

var backgroundUpdateTask: UIBackgroundTaskIdentifier!

func beginBackgroundUpdateTask() {
    print("beginBackgroundUpdateTask")
    self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    print("endBackgroundUpdateTask")
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

func doBackgroundTask() {
    print("Strart")
    DispatchQueue.global().async {
        self.beginBackgroundUpdateTask()

        // Do something with the result.
        let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(AppDelegate.displayAlert), userInfo: nil, repeats: true)
        RunLoop.current.add(timer, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        // End the background task.
        self.endBackgroundUpdateTask()
    }

    print("Finish")
}

func displayAlert() {
    print("displayAlert")
    let note = UILocalNotification()
    note.alertBody = "As a test I'm hoping this will run in the background every X number of seconds..."
    note.soundName = UILocalNotificationDefaultSoundName
    UIApplication.shared.scheduleLocalNotification(note)
}

func applicationDidEnterBackground(_ application: UIApplication) {
    log.debug("applicationDidEnterBackground")
    self.doBackgroundTask()

}

编辑

var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var timerr: Timer?

func beginBackgroundUpdateTask() {
        appDeligate.log.debug("beginBackgroundUpdateTask")
        self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    appDeligate.log.debug("endBackgroundUpdateTask")
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
    timerr = nil
}

func doBackgroundTask() {
    print("Strart")
    DispatchQueue.global().async {
        self.beginBackgroundUpdateTask()

        // Do something with the result.
        self.timerr = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(TestViewController.displayAlert), userInfo: nil, repeats: true)
        RunLoop.current.add(self.timerr!, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        // End the background task.
        self.endBackgroundUpdateTask()
    }

    print("Finish")
}

func displayAlert() {
    print("displayAlert")
    let note = UILocalNotification()
    note.alertBody = "As a test I'm hoping this will run in the background every X number of seconds..."
    note.soundName = UILocalNotificationDefaultSoundName
    UIApplication.shared.scheduleLocalNotification(note)
}

真正的问题是定时器,我需要把这行

timerr?.invalidate()

此处

func endBackgroundUpdateTask() {
    appDeligate.log.debug("endBackgroundUpdateTask")
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
    timerr?.invalidate()
}

但无论如何它有点奇怪,因为我想如果我停止 backgroundUpdate() 里面的所有任务都必须自动失效和清除,但是没有。

感谢@matt