UserDefaults Bool Key被删除

时间:2013-11-03 15:42:01

标签: ios bundle nsuserdefaults

我正在创建一个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键。

我错过了什么?为什么这把钥匙消失了?

2 个答案:

答案 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;
    }

无需再次请求用户默认值。