DispatchQueue.global (qos: .default) продолжается, когда приложение заблокировано или заблокирован экран, как приостановить? - PullRequest
3 голосов
/ 01 апреля 2019

Swift Новичок: перенос кода интеграции Objective-C AppleHealth в Swift, который вызывается Flutter / Dart.Когда я создаю фоновый экран или блокирую экран унаследованного приложения Obj-C, оно практически сразу приостанавливает все выполнение.Однако такое же поведение не происходит в моем порте кода Swift, я использую тот же DispatchQueue в Swift, что и в устаревшем приложении Obj-C,

Причина, по которой важно приостановить работу, заключается в том, что когда-то пользовательблокирует экран iPhone, AppleHealth шифрует все его данные, и он недоступен.Также я правильно понимаю, что когда вы приостанавливаете DispatchQueue, выполняемый в данный момент блок завершится, но последующие блоки не начнут выполняться.Насколько я могу судить, мой порт кода Swift имитирует логику Obj-C, и любые намеки на то, почему он ведет себя по-другому или чего мне не хватает, будут с благодарностью приняты.

Я отправляю, используя

DispatchQueue.global(qos: .default).async { 
/* code */ 
}

Если бы можно было заставить новое приложение немедленно приостановить весь исполняемый код, который я отправил в DispatchQueue, при фоновом режиме или экранировании блокировки я был бы очень рад.

1 Ответ

2 голосов
/ 01 апреля 2019

Когда приложение приостанавливается, все работающее, будь то в основной очереди или в фоновом режиме global очередь, также приостанавливается.

Вы делаете что-нибудь в приложении, чтобы оно работало в фоновом режиме?Например, если вы запускаете приложение через отладчик XCode (например, чтобы посмотреть свои операторы print или что-то еще), это изменяет жизненный цикл приложения и поддерживает его работу в фоновом режиме.(«Наблюдательный эффект» XCode? Lol.) Например, вы запускаете это через отладчик XCode?

Кроме того, если в вашем приложении включены определенные фоновые функции, это также может поддерживать его в рабочем состоянии.

Поскольку вы не можете запустить приложение через отладчик Xcode для просмотра жизненного цикла приложения, я продемонстрируюпроцесс, использующий Unified Logging для отслеживания прогресса моего приложения.С помощью Unified Logging я могу отслеживать эти записи журнала на моем iPhone из моей консоли MacOS, даже не запуская Xcode.

Рассмотрим что-то вроде:

import UIKit
import os.log

private let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "ViewController")

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        os_log("viewDidLoad", log: log, type: .debug)
        startTask()
    }

    func startTask() {
        DispatchQueue.global().async {
            var i = 0
            while true {
                let start = Date()
                while Date().timeIntervalSince(start) < 1 { }
                os_log("tick %d", log: log, type: .debug, i)
                i += 1
            }
        }
    }
}

(Обратите внимание, что обычно вы никогда не должны вращаться таким образом, но я сделал это, чтобы создать процесс, который намеренно удерживает процессор занятым.)

Итак, я:

  • установлен на моем устройстве,
  • выйти из Xcode,
  • запустил консольное приложение macOS,
  • в консольном приложении я включил ведение журнала отладки с помощью команды «Действие» »« Включить сообщения отладки »,
  • отфильтровал журнал, так что я вижу активность только в своей подсистеме (лично я всегда использую для этого свой идентификатор пакета)и
  • запустить мое приложение непосредственно на моем устройстве iOS.

Мы ясно видим, что приложение останавливается (включая эту задачу, выполняющуюся в фоновой очереди), когда я приостанавливаю приложение.(Очевидно, в дополнение к вышеприведенным os_log сообщениям я поместил аналогичные операторы в свой AppDelegate, чтобы и здесь видеть события жизненного цикла.) В любом случае, это то, что показала моя консоль:

Console

Я покинул свое приложение, когда появился «галочка 5», прошло несколько секунд, прежде чем приложение было полностью приостановлено, но вы можете видеть, что приложение перестало работать после «галочка 7 »и« applicationDidEnterBackground »появились.И я перезапустил приложение примерно через 10 секунд, после чего вы видите, что приложение возвращается к жизни и возобновляет отсчет времени, прямо там, где оно остановилось.

Итак, если ваше приложение все еще работает, либо оно подключенок отладчику XCode, или у вас есть что-то, что держит приложение в фоновом режиме.Но обычно, когда вы выходите из приложения, оно приостанавливается, и вы увидите поведение, подобное описанному выше.

Кстати, для получения дополнительной информации об использовании Unified Logging, настройке устройства и т. Д. См. WWDC.Видео 2016 года Unified Logging и отслеживание активности .

...