我正在创建一个userDefault bool密钥,该密钥在我尝试更改密钥值之前一直有效。更改密钥的值后,密钥似乎从应用程序包中消失。例如,以下代码在我的GameManager的init例程中(这是一个服务于我游戏应用程序所有级别的单例)并在我的应用程序首次加载时运行:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // get the shared defaults object
if (defaults) {
if ([defaults boolForKey:@"Sound Effects ON"]) {
isSoundEffectsON = [defaults boolForKey:@"Sound Effects ON"];
}
else {
[defaults setBool: YES forKey:@"Sound Effects ON"];
isSoundEffectsON = YES;
[defaults synchronize]; // save the initial state
}
}
首次输入此代码时,执行路径将使用else子句,因为@“Sound Effects ON”的userDefault当前不存在。如果我对@“Sound Effects ON”不执行任何操作并重新启动应用程序(从而重新输入此代码),则执行路径将获取@子句并检索@“Sound Effects ON”的存储值(表示该键已经存在)成功存储在应用程序包中。
稍后当我的一个游戏关卡运行且用户决定更改此键的值时,执行以下代码:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // get the shared defaults object
if ([[GameManager sharedGameManager] isSoundEffectsON]) {
[[GameManager sharedGameManager] setIsSoundEffectsON:NO];
if (defaults) {
// Update the state for sound effects
[defaults setBool: NO forKey:@"Sound Effects ON"];
[defaults synchronize]; // save the current state
}
} else {
[[GameManager sharedGameManager] setIsSoundEffectsON:YES];
if (defaults) {
// Update the state for sound effects
[defaults setBool: YES forKey:@"Sound Effects ON"];
[defaults synchronize]; // save the current state
}
}
如果isSoundEffects先前已开启,则@“Sound Effects ON”布尔值设置为NO并且userDefault已同步(可能是为了保存该值)。当执行此执行路径时,它似乎从应用程序包中删除此密钥的userDefault。我这样说是因为当重新加载应用程序并且GameManager init中的代码再次执行时,else子句运行表明@“Sound Effects ON”没有userDefault键。
我错过了什么?为什么这把钥匙消失了?
答案 0 :(得分:3)
关键不会消失。 boolForKey:
返回BOOL值本身,因此如果将其设置为NO,则代码if ([defaults boolForKey:@"Sound Effects ON"]) {...}
将正确地执行其块。如果您要测试密钥的状态而不是其值,则应使用objectForKey:
,它将返回nil
,表示密钥不存在,或者NSNumber
(您可以通过询问boolValue
来获取BOOL值。例如:
if ([defaults objectForKey:@"Sound Effects ON"]) {
// key is set
BOOL value = [defaults boolForKey:@"Sound Effects ON"];
} else {
// key is not set
}
尽管如此,如果你要做的就是指定YES是默认值,你可以完全摆脱这个逻辑并使用{{1}}来指定NSUserDefaults应该的值在通过registerDefaults:
设置值之前。例如:
setX:forKey:
在尝试访问默认设置之前,请在您的应用委托中调用此代码。您应该只使用您想要特定默认值的所有键调用一次。
答案 1 :(得分:1)
设置为NO
的BOOL实际上与不存在的密钥相同。在这两种情况下,if ([defaults boolForKey:@"Sound Effects ON"]) {
都不会触发。
您的问题似乎是对布尔值如何工作或if
语句如何工作的基本误解。
例如,这段代码:
if ([defaults boolForKey:@"Sound Effects ON"]) {
isSoundEffectsON = [defaults boolForKey:@"Sound Effects ON"];
}
等于
if ([defaults boolForKey:@"Sound Effects ON"]) {
isSoundEffectsON = YES;
}
无需再次请求用户默认值。