简体   繁体   English

当我的应用程序在iOS上终止时,保存NSUserDefaults的正确方法是什么

[英]What is the correct way to save NSUserDefaults when my app is terminated on iOS

I need to save my NSUserDefault when my app is completely quit in iOS. 当我的应用程序在iOS中完全退出时,我需要保存我的NSUserDefault not didenterbackground and foreground . 不是didenterbackgroundforeground Only when user kill my app with minus(-) sign in iOS. 仅当用户在iOS中使用减号( - )符号终止我的应用时。

So i write following codes in applicationWillTerminate of AppDelegate . 所以我在AppDelegate applicationWillTerminate中编写以下代码。

- (void)applicationWillTerminate:(UIApplication *)application
{

    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"iCloud"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

But it doesn't save to NSUserDefault . 但它不保存到NSUserDefault

So where should i write to save my data? 那么我应该在哪里写保存我的数据?

From Apple Doc : 来自Apple Doc

For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app. 对于不支持后台执行或与iOS 3.x或更早版本链接的应用程序,当用户退出应用程序时,始终会调用此方法。 For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. 对于支持后台执行的应用程序,当用户退出应用程序时通常不会调用此方法,因为在这种情况下应用程序只是移动到后台。 However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason. 但是,可以在应用程序在后台运行(未暂停)并且系统由于某种原因需要终止它的情况下调用此方法。

It's not necessary that applicationWillTerminate will be called when app exits, it may not be called when your app supports background execution. 当应用程序退出时,不必调用applicationWillTerminate ,当您的应用程序支持后台执行时, 可能不会调用它

You can use UIApplicationExitsOnSuspend to specifies that the app should be terminated rather than moved to the background when it is quit. 您可以使用UIApplicationExitsOnSuspend指定应该终止应用程序而不是在退出时移动到后台。

I afraid, there isn't any delegate method which will surly handle app's force-quite scenario. 我担心,没有任何委托方法可以狡猾地处理应用程序的力量 - 非常情况。

Hope this may help you in solving your problem. 希望这可以帮助您解决问题。

When an app is ended from the multitasking bar, is is simply killed. 当应用程序从多任务栏结束时,就会被杀死。 There is no delegate method called. 没有调用委托方法。 willTerminate is called for apps that do not support multitasking when the home button is hit. 当主页按钮被点击时,将调用不支持多任务处理的应用程序的willTerminate

Apps by default support multitasking, so you should be doing everything you need to do in didEnterBackground. 默认情况下,应用程序支持多任务处理,因此您应该在didEnterBackground中执行所有操作。 After that, you can't guarantee that any of your code will be called again. 之后,您无法保证将再次调用您的任何代码。

You can set your Application does not run in background" = "YES" in your info.plist file and you can see applicationWillTerminate delegate getting called & storing values in NSUserDefaults . 您可以将您的Application does not run in background" = "YES"设置为Application does not run in background" = "YES" info.plist文件Application does not run in background" = "YES" ,您可以看到在NSUserDefaults调用applicationWillTerminate委托NSUserDefaults

在此输入图像描述

The problem is that applicationWillTerminate is not getting called at all. 问题是applicationWillTerminate根本没有被调用。

Change your applicationDidEnterBackground as below and kill your application within 20 seconds. 如下所示更改applicationDidEnterBackground并在20秒内终止您的应用程序。 You can see applicationWillTerminate getting called & setting your iCloud value properly in NSUserDefaults 您可以在NSUserDefaults看到applicationWillTerminate被调用并正确设置您的iCloud

- (void)applicationDidEnterBackground:(UIApplication *)application
{

    __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;
        }
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM