beginBackgroundTaskWithExpirationHandler вызывает endBackgroundTask, но не завершает процесс

У меня есть длительный процесс, который я хочу запустить, даже если приложение идет в фоновом режиме. Я beginBackgroundTaskWithExpirationHandler: метод beginBackgroundTaskWithExpirationHandler: метода приложения, и в expirationBlock я endBackgroundTask приложения. Вот реализация:

 __block UIBackgroundTaskIdentifier task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [[UIApplication sharedApplication] endBackgroundTask:task]; task = UIBackgroundTaskInvalid; }]; dispatch_queue_t queue = dispatch_queue_create("com.test.test1234", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{ // My Task goes here }); 

В некоторых случаях у моей последовательной очереди больше задач, которые невозможно выполнить за время, предоставленное системой. Таким образом, блок истечения будет выполнен и в этом я заканчиваю UIBackgroundTaskIdentifier но не останавливаю процесс отправки (я даже не могу отменить отправку).

В документе Apple говорится:

Каждый вызов метода beginBackgroundTaskWithName: expirationHandler: или beginBackgroundTaskWithExpirationHandler: генерирует уникальный токен для связи с соответствующей задачей. Когда ваше приложение завершает задачу, оно должно вызвать метод endBackgroundTask: с соответствующим токеном, чтобы система узнала, что задача завершена. Невозможность вызвать метод endBackgroundTask: для фоновой задачи приведет к прекращению действия вашего приложения. Если вы предоставили обработчик срока действия при запуске задачи, система вызывает этот обработчик и дает вам последний шанс прекратить выполнение задачи и избежать ее завершения.

Итак, в соответствии с этим, если я не вызываю endBackgroundTask: мое приложение будет прекращено, что нормально.

Мой вопрос: с моей текущей реализацией, что, если я вызову endBackgroundTask: в блоке expirationHandler и моей задаче диспетчерской очереди не получается? Мое приложение будет прекращено или будет приостановлено?

благодаря

Вот несколько сценариев, которые нужно обрабатывать при использовании beginBackgroundTaskWithExpirationHandler иначе ваше приложение terminate .

Сценарий 1 : ваше приложение работает в Foreground . вы начинаете beginBackgroundTaskWithExpirationHandler затем войдите в Background режим. ваше приложение держится надолго.

Сценарий 2 : ваше приложение работает в Foreground . вы начинаете beginBackgroundTaskWithExpirationHandler затем войдите в Background режим. Затем вернитесь в режим endBackgroundTask и вы не вызываете endBackgroundTask тогда ваше приложение все равно execute background queue режим, поэтому он будет endBackgroundTask этот процесс в течение следующих 3 minute (после того, как IOS 7 представит перед IOS 7, время выполнения процесса составляло 10 минут). поэтому вам нужно будет отменить фоновые очереди, а задача выйдет из фоновой очереди и войдет в очередь переднего плана .

Итак, вот код, который показывает вам. что лучше всего обрабатывать фоновый процесс.

Шаг 1: объявить __block UIBackgroundTaskIdentifier bgTask как глобальную переменную.

Шаг 2: Чтобы добавить следующий код в applicationDidEnterBackground.

 - (void)applicationDidEnterBackground:(UIApplication *)application { bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ bgTask = UIBackgroundTaskInvalid; }]; } 

Шаг 3: Остановите обработчик фонового задания, когда приложения заходят в режим переднего плана.

 - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. [[UIApplication sharedApplication] endBackgroundTask:bgTask]; } 

Надеюсь, это поможет вам.

Если вы не вызываете endBackgroundTask в своем обработчике истечения срока действия, ваше приложение будет прекращено.

Как только вы вызываете endBackgroundTask в своем обработчике истечения срока действия, вы сообщаете ОС «ОК, я покончил с критическими задачами. Это зависит от вас». После этого ваше приложение может быть приостановлено на некоторое время и прекращено позже, или оно может быть немедленно прекращено в зависимости от системных ресурсов.

Давайте будем гением компьютера.