applicationWillTerminate, когда он вызывается, а когда нет - PullRequest
61 голосов
/ 19 октября 2011

Привет, я прочитал несколько вопросов на SO о том, что applicationWillTerminate вызывается, а не вызывается.

Я хотел бы обобщить то, что я понял, поскольку есть несколько постов, которые говорят по-разному.

  1. Для IOS (без многозадачности) он вызывается всегда при нажатии кнопки home.

  2. Для IOS 4 и выше

    а. не вызывается при нажатии кнопки домой (когда приложение переходит в фоновый режим)

    б. он вызывается при закрытии приложения из многозадачной док-станции, и если у приложения внезапный флаг завершения в файле info.plist отключен, в противном случае он не вызывается. (Я установил «Приложение должно получать события App Died», и даже тогда при закрытии приложения из многозадачной док-станции функция завершения не вызывалась)

Исходя из этого у меня была пара вопросов

Это хорошая практика, чтобы установить, что приложение должно получать флаг событий App Died? (Я установил «Приложение должно получать события App Died», и даже после закрытия приложения из многозадачной док-станции функция завершения не вызывалась)

или

Является ли регистрация в "UIApplicationWillTerminateNotification" лучше, чем настройка info.plist?

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

или

РЕДАКТИРОВАТЬ (1): Когда приложение завершается, в приложение отправляется следующее. Как мне его поймать?

Программа получила сигнал: «SIGKILL».

РЕДАКТИРОВАТЬ (2):

Обратите внимание: он не вызывается в IOS 4 и выше при удалении из дока многозадачности. Вы можете подумать, что это так. Но в моем случае это не так.

Я спрашиваю, знает ли кто-нибудь почему? Есть ли что-то еще, что я пропускаю.

Также обратите внимание, что я установил «Приложение должно получать события App Died», и даже тогда оно не вызывается.

РЕДАКТИРОВАТЬ (3):

Ответ на следующий вопрос также не сработал. applicationWillTerminate не вызывается

Кто-нибудь сталкивался с такой же проблемой, как я?

Ответы [ 6 ]

49 голосов
/ 19 октября 2011

Короче говоря, если у вас UIApplicationExitsOnSuspend в вашем Info.plist не установлено значение YES, в iOS4 и выше нет гарантии, что applicationWillTerminate: когда-либо будет вызван.

Как документация гласит:

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

(Выделение мое.)

Если вам нужно что-то сделать до выхода из приложения, вам нужно сделать это в applicationDidEnterBackground:. Нет возможности поймать Сигкилла.

28 голосов
/ 28 февраля 2013

Я вижу, что -applicationWillTerminate: вызывают с помощью следующего теста. В новом проекте (я использовал шаблон «Single View Application»), добавьте в AppDelegate следующее:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSLog(@"%s", __PRETTY_FUNCTION__);

    __block UIBackgroundTaskIdentifier identifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        if (identifier != UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:identifier];
            identifier = UIBackgroundTaskInvalid;
        }
    }];

    dispatch_async(dispatch_get_main_queue(), ^{
        for (int i=0; i < 20; i++) {
            NSLog(@"%d", i);
            sleep(1);
        }
        if (identifier != UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:identifier];
            identifier = UIBackgroundTaskInvalid;
        }
    });
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

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

Итак, чтобы протестировать его, запустите приложение, нажмите кнопку «Домой», чтобы отправить приложение в фоновый режим, а затем, до истечения 20-секундной задержки, удалите приложение из переключателя приложений. После конца 20-х годов вызывается -applicationWillTerminate:. Вы можете посмотреть консоль в Xcode, чтобы убедиться, что это так.

Я попробовал это в iOS Simulator для iOS 5.1 и 6.1 (оба iPhone) и увидел, что это происходит в обоих случаях. Я также тестировал на iPhone 4S под управлением iOS 6.1.2 и видел то же поведение.

4 голосов
/ 22 апреля 2015

Как я знаю, в 3 случаях ваше приложение умрет.

  1. Завершено конечным пользователем, вы можете сделать что-то в -[UIApplication applicationWillEnterBackground:], в этом случае -[UIApplication applicationWillTerminate:] НЕ будет вызван.

  2. Сброс системы, например, недостаточно памяти, вы можете что-то сделать в -[UIApplication applicationWillTerminate:], и в этом случае мы НЕ знаем, был ли вызван applicationWillEnterBackground:;

  3. Сбой, ничего не поделаешь, кроме использования какого-либо инструмента отчетности о сбоях. (Отредактировано: ловить SIGKILL невозможно)

3 голосов
/ 12 сентября 2012

Источник: http://www.cocos2d -iphone.org / forum / topic / 7386

Я скопировал свой код сохранения состояния из applicationWillTerminate в applicationDidEnterBackground, а также добавил многозадачный бинарчто я вызываю только сохранение состояния в applicationDidEnterBackground.ПОТОМУ ЧТО есть один экземпляр на многозадачном устройстве, где вызывается applicationWillTerminate: если приложение находится на переднем плане и вы выключаете устройство.В этом случае и applicationDidEnterBackground, и applicationWillTerminate вызываются.

1 голос
/ 21 августа 2015

Как мы знаем, приложение имеет только 5 секунд при вызове -applicationWillTerminate. Так что если кто-то хочет обновить сервер в этот момент. Чем использовать Синхронный звонок.

[NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:&error];

Примечание: - -applicationWillTerminate не будет вызывать, если приложение будет убито из приостановленного состояния. Приостановленное состояние означает, что приложение не работает в backgroupd. Одним из решений для этого является использование фоновой задачи.

0 голосов
/ 19 февраля 2016

// абсолютный ответ applicationWillTerminate

func applicationWillTerminate (application: UIApplication) {

    print("applicatoinWillTerminate")

    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

шаг 1: команда + shift + h (двойной щелчок (вкладка))

шаг 2: переместить верхнюю сторону приложения (убить)

шаг 3: applicationWillTerminate Work

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