NSUserDefaults不保存

我在我的精灵工具包应用程序中,我的NSUserDefaultsvariables不起作用的问题。 在createSceneContents (我知道被称为)

 if (![defaults objectForKey:@"obj"]) { difficultyLabel.text = @"Difficulty: Easy"; [defaults setObject:@"Easy" forKey:@"obj"]; } else { difficultyLabel.text = [NSString stringWithFormat:@"Difficulty: %@", [defaults objectForKey:@"diff"]]; } 

然后当你点击SKLabelNode来改变难度和这个代码被调用

 if ([label.text isEqualToString:@"Difficulty: Easy"]) { label.text = @"Difficulty: Hard"; [defaults setObject:@"Hard" forKey:@"obj"]; NSLog(@"%@",[defaults objectForKey:@"obj"]); } else { label.text = @"Difficulty: Easy"; [defaults setObject:@"Easy" forKey:@"obj"]; NSLog(@"%@",[defaults objectForKey:@"obj"]); 

但是当我停止程序并再次运行时,它总是说难度:容易。 有什么build议么?

正如rmaddy的回答所解释的, NSUserDefaults不会立即将数据写入长期存储。

当你调用setObject:forKey: ,这些值被保存在临时内存中,所以如果你尝试调用objectForKey: setObject:forKey: ,它会返回内存中的值(如果存在的话),如果没有的话,它去寻找什么被保存到长期存储。

在后台,设备最终将这些值保存到永久存储。 这是操作系统处理的东西,但是在你的应用程序的正常运行中,大多数情况下不需要立即将这些值存储到永久存储器中,所以当操作系统进行优化时,让操作系统执行此操作(I想象一下,操作系统可能会按照一定的时间同步每个应用程序的用户默认设置,并尽可能地在处理器空闲的时候尝试这样做)。

但是据说,正如rmaddy所解释的那样,如果你有一些重要的东西需要立即保存到永久存储器中,你可以随时调用synchronize 。 请记住,只要你的应用程序在debugging模式下不会被杀死,那么你设置的存储在用户默认值中的值将被存储。

但是为了你自己的利益,如果你想绝对肯定的话,你可以把它作为rmaddybuild议的在applicationDidEnterBackground synchronize一个调用。 请记住,如果你杀了应用程序,这个方法不会被调用。

当你说你“停止计划”时,你的意思是什么? 你在debugging器中运行,并杀死应用程序,并再次运行它? NSUserDefaults不会立即保存您的更改。 在写入重要数据之后调用[defaults synchronize] ,或者至less将这样的调用添加到您的应用程序委托的applicationDidEnterBackground方法中。 然后确保在杀死它之前将您的应用程序置于后台,以确保首先写入数据。

储藏:

 NSString * str = @"name123"; NSUserDefaults *def=[NSUserDefaults standardUserDefaults]; [def setObject:str forKey:@"Key"]; [def synchronize]; NSLog(@"str = = %@",str); 

检索:

 NSUserDefaults *def=[NSUserDefaults standardUserDefaults]; NSString *str2 = [def valueForKey:@"Key"]; NSLog(@" Saved str = = %@",str2); 

我发现NSUserDefaults没有保存的另一个原因,下面的代码可以使NSUserDefaults中的值不保存:

 NSUserDefaults *def= [[NSUserDefaults standardUserDefaults] init]; ... NSUserDefaults *def= [[NSUserDefaults standardUserDefaults] initWithSuiteName:@"123"]; 

你可以在你的项目中searchNSUserDefaults来捕获那些init两次的bug。