Уточнение, когда метод cancelByProductionResumeData вызывает обработчик завершения

В документации Apple есть следующий пример для получения времени выполнения в фоновом режиме и выполнения некоторых задач после того, как приложение было переведено в фоновый режим. В чем преимущество выполнения задачи с использованием dispatch_async? т.е. когда приложение находится в фоновом режиме, в чем разница между работой в «основном потоке» и «асинхронно в фоновом потоке»?

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
    // Clean up any unfinished task business by marking where you
    // stopped or ending the task outright.
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
    }];

   // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task, preferably in chunks.

     [application endBackgroundTask:bgTask];
     bgTask = UIBackgroundTaskInvalid;
    });
}

person Smart Home    schedule 28.10.2015    source источник


Ответы (2)


После некоторых экспериментов я вижу две проблемы, если вы не вызываете dispatch_async. Если вы выполняете длительные задачи (например, делаете что-то в цикле while), это не позволит перезапустить приложение, если вы попытаетесь вернуть его на передний план. Кроме того, я вижу, что никакие сетевые делегаты не вызываются, даже если приложение получает данные с дальнего конца.

person Smart Home    schedule 29.10.2015

Согласно документации у вас есть 5 секунд на выполнение любых задач в applicationDidEnterBackground: и обратно. Если вам нужно дополнительное время - вы должны использовать beginBackgroundTaskWithName:.

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

Вот почему вы должны запросить дополнительное фоновое выполнение через вызов beginBackgroundTaskWithName: и запустить задачу асинхронно в каком-то потоке. Таким образом, вы будете следовать правилу «5 секунд».

person sgl0v    schedule 29.10.2015
comment
Кажется, что правило 5 секунд применяется только в том случае, если я не вызываю beginBackgroundTaskWithName . То есть, как только я вызываю beginBackgroundTaskWithName, я не видел проблем с тем, что iOS убивает мое приложение из-за истечения срока действия 5 с, если синхронно вводится цикл while (1). Единственная проблема, которую я обнаружил, заключается в том, что это приложение перестает отвечать на запросы при повторном запуске. - person Smart Home; 31.10.2015