Когда приложение iOS переходит в фоновый режим, приостановлены ли длительные задачи?

Да, я знаю, если я хочу, чтобы приложение реагировало на многозадачные действия пользователей, такие как переход на другое приложение, я должен иметь дело с

- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application

Что делать, если мое приложение выполняет довольно долгую операцию (например, загрузку большого файла), и пользователь заставляет мое приложение войти в фоновый режим? Будет ли эта операция автоматически приостановлена ​​и возобновлена, когда пользователь вернется в мое приложение?

Что именно произойдет за сценой, когда мое приложение войдет в фоновый режим или возобновится на переднем плане?

Что делать, если пользователи позволяют моему приложению перейти на фоновый режим, выполнение моего приложения находится только в середине метода?

Например, мое приложение делает

for (int i = 1 to 10000K) {
    do some calculation;
}

Когда я == 500K, пользователь переключается на другое приложение. Что происходит с циклом for в моем приложении?

Ответ 1

Из Руководство по программированию приложений iOS:

Ваш делегат applicationDidEnterBackground: имеет приблизительно 5 секунд, чтобы закончить любые задачи и вернуться. На практике, этот метод должен возвращаться как можно быстрее. Если метод не возвращаться до истечения времени, ваше приложение убито и очищено от Память. Если вам все еще нужно больше времени для выполнения задач, вызовите beginBackgroundTaskWithExpirationHandler: метод запроса фона времени выполнения, а затем запускать любые длительные задачи во вторичном нить. Независимо от того, начинаете ли вы какие-либо фоновые задачи, applicationDidEnterBackground: метод все равно должен выйти в течение 5 секунд.

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

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

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

Ответ 2

Если вы выполняете какую-то операцию, которая может потреблять время, и вы не хотите ее убивать, вы можете продлить время для своей работы, выполнив в UIBackground Task i

{
    UIBackgroundTaskIdentifier  taskId = 0;
    taskId = [application beginBackgroundTaskWithExpirationHandler:^{
        taskId = UIBackgroundTaskInvalid;
    }];

// Execute long process. This process will have 10 mins even if your app goes in background mode.

}

Аргумент блока, называемый "обработчик", - это то, что произойдет, когда истечет срок действия фоновой задачи (10 минут). Вот ссылка на documentation

Ответ 3

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

https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

Более того, если вы вписываетесь в одну из этих категорий, скорость обновления вашего приложения определяется алгоритмом Apple, который учитывает использование вашего приложения на этом устройстве и других приложениях. Если ваше приложение используется чаще, он получает больше фонового времени. Это всего лишь одна переменная, но вы понимаете, что распределение фонового времени зависит от приложения и приложения, а не под вашим контролем.