applicationWillTerminate何时被调用,何时不被调用

时间:2011-10-19 07:42:30

标签: iphone ios4

您好我已经阅读了几个关于applicationWillTerminate被调用而没有被调用的问题。

我想总结一下我所理解的内容,因为有几个帖子的说法不同。

  1. 对于IOS(没有多任务处理),只有在按下主页按钮时才会调用它。

  2. 适用于IOS 4及以上

    一个。当按下主页按钮时(当应用移动到背景时)

    湾从多任务停靠平台关闭应用程序时调用它,如果应用程序在info.plist中有一个突然终止标志禁用,则不会调用它。 (我设置了“应该应用程序应该死的事件”,甚至在从多任务平台关闭应用程序时,终止功能没有被调用)

  3. 基于此,我有几个问题

    设置应用程序应该获取App Died事件标志是一个好习惯吗? (我设置了“Application应该得到应用程序死亡事件”,然后在从多任务停靠点关闭应用程序时,终止函数没有被调用)

    注册“UIApplicationWillTerminateNotification”比info.plist设置更好吗?

    基本上我只需要在应用程序终止时做一些工作,而不是在它移动到后台时做。

    编辑(1): 当应用程序终止时,以下内容将发送到APP。我怎么抓住它?

    收到信号:“SIGKILL”。

    编辑(2):

    请注意:从多任务底座上卸下时,不会在IOS 4及更高版本中调用它。你可能会认为是。但就我而言,事实并非如此。

    我问是否有人知道为什么?还有别的我想念的东西。

    另请注意我设置了“应用程序应该获取应用程序死亡事件”,即使这样也没有被调用。

    编辑(3):

    以下问题的答案也行不通。 applicationWillTerminate does not get invoked

    任何人都面临与我类似的问题吗?

7 个答案:

答案 0 :(得分:49)

简而言之,除非您将Info.plist中的UIApplicationExitsOnSuspend设置为YES,否则在iOS4及更高版本中无法保证applicationWillTerminate:将被调用。

正如the documentation所说:

  

对于支持后台执行的应用程序,此方法是   通常在用户退出应用程序时不会调用,因为   在这种情况下,应用程序只是移动到后台。但是,这个   在运行应用程序的情况下,可以调用可能方法   后台(未暂停),系统需要终止它   由于某种原因

(强调我的。)

如果您需要在应用退出之前执行某些操作,则需要在applicationDidEnterBackground:中执行此操作。没有办法抓住SIGKILL。

答案 1 :(得分:28)

我看到-applicationWillTerminate:通过以下测试被调用。在一个新项目中(我使用了“单一视图应用程序”模板),将以下内容添加到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模拟器中为iOS 5.1和6.1(两者都是iPhone)尝试了这一点,并且在两种情况下都看到了这种情况。我还在运行iOS 6.1.2的iPhone 4S上进行了测试,看到了相同的行为。

答案 2 :(得分:4)

据我所知,有3种情况会导致您的应用程序死亡。

  1. 由最终用户终止,您可以在-[UIApplication applicationWillEnterBackground:]中执行某些操作,在这种情况下,-[UIApplication applicationWillTerminate:]将不会被调用。

  2. 系统丢弃,例如内存不够,你可以在-[UIApplication applicationWillTerminate:]中执行某些操作,在这种情况下,我们不知道是否已调用applicationWillEnterBackground:;

  3. 崩溃,除了使用某种崩溃报告工具外什么也做不了。 (编辑:捕捉SIGKILL是不可能的)

答案 3 :(得分:3)

来源:http://www.cocos2d-iphone.org/forum/topic/7386

  

我将我的状态保存代码从applicationWillTerminate复制到applicationDidEnterBackground,并且还添加了一个multitaskingEnabled布尔值,以便我只在applicationDidEnterBackground中调用状态保存。因为,多任务设备上有一个实例,其中调用applicationWillTerminate:如果应用程序位于前台,则关闭设备电源。在这种情况下,将调用applicationDidEnterBackground和applicationWillTerminate。

答案 4 :(得分:1)

我们知道,当-applicationWillTerminate被调用时,应用程序只有5秒。所以如果有人想在那时更新服务器。比使用 同步通话。

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

注意: - -applicationWillTerminate如果应用程序被挂起状态被杀死,则不会调用。暂停状态意味着应用程序在backgroupd中无法正常工作。其中一个解决方案是使用后台任务。

答案 5 :(得分:0)

基于Andrew's test,我了解applicationWillTerminate(_:)的文档具有以下说明:

对于不支持后台执行或与iOS 3.x或更早版本链接的应用程序,总是在用户退出应用程序时调用此方法。对于支持后台执行的应用程序,当用户退出应用程序时,通常不将其称为 [立即] ,因为在这种情况下,该应用程序只是移至后台。但是,在应用程序在后台运行(未挂起)并且系统出于某种原因需要终止该应用程序的情况下,可以将该方法称为 [而不是beginBackgroundTask(expirationHandler:)]

答案 6 :(得分:-1)

//绝对答案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(双击(tab))

第2步:移动app top side(kill)

第3步:applicationWillTerminate工作