3

我有以下代码应该更新 NSUserDefaults 中的值:

- (id) createBoardWithTitle:(NSString *)pTitle withScores:(NSArray *)pScores andNames:(NSArray *)pNames andDisplayStrings:(NSArray *)pStrings orderBy:(NSString *)pOrder ofType:(NSString *)pType
{

    if((self == [super init]))
    {

        boardEntries = [NSMutableArray arrayWithCapacity:10];

        // Build the data

            for(...){
               // populate boardEntries
            }


        // create an Dictionary to save
        NSDictionary *savedData = [NSDictionary dictionaryWithObjectsAndKeys:pType, @"type", pOrder, @"order", boardEntries, @"entries", nil];

            // Load the old boards
        NSDictionary *existingBoards = [[NSUserDefaults standardUserDefaults] objectForKey:@"BlockDepotLeaderboards"];

            // Create a mutable dictionary to replace the old immutable dictionary
        NSMutableDictionary *newBoards = [NSMutableDictionary dictionaryWithCapacity:[existingBoards count]+1];

            // transfer the old dictionary into the new dictionary
        [newBoards addEntriesFromDictionary:existingBoards];

            // add the new board to the new dictionary
        [newBoards setObject:savedData forKey:pTitle];

            // check to make sure it looks like it should by eye
        NSLog(@"New Boards: %@", newBoards);

            // Replace the old date in NSUserdefaults
        [[NSUserDefaults standardUserDefaults] setObject:newBoards forKey:@"BlockDepotleaderboards"];
            // Update: Do I really need to call this?
        [[NSUserDefaults standardUserDefaults] synchronize];

            // Check to make sure it looks as it should by eye
        NSLog(@" Defaults--- %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"BlockDepotLeaderboards"]);
    }

    return self;

}

据我所知,这是相关的代码。它可能比它需要的“更冗长”。但据我了解,从 NSUserDefaults 返回的任何内容都是不可变的,因此我必须将其重新创建为 Mutable 对象,添加需要添加的内容,然后替换 NSUserDefaults 中的对象。而且我认为我在上面尝试的应该可行。

NSLog(@"New Boards: %@", newBoards) id 的输出

New Boards: {
    "Marathon: Times" =     {
        entries =         (
                        {
                displayString = "10:00";
                name = "Tom Elders";
                score = 600;
            },
                        {
                displayString = "10:30";
                name = "A.R. Elders";
                score = 630;
            },
                        {
                displayString = "11:00";
                name = "L. Lancaster-Harm";
                score = 660;
            },

            // and so on.....

        );
        order = ASC;
        type = TIMES;
    };
    String = Test;
}

"String = test" 只是一个测试条目,在 AppDelegate.m 文件中设置如下:

if(![[NSUserDefaults standardUserDefaults] objectForKey:@"BlockDepotLeaderboards"]){

    NSMutableDictionary *leadboardHolder = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Test", @"String", nil];      
    [[NSUserDefaults standardUserDefaults] setObject:leadboardHolder forKey:@"BlockDepotLeaderboards"];
    [[NSUserDefaults standardUserDefaults] synchronize];



}else{
    NSLog(@"Leaderboards Dict Exists %@", [NSUserDefaults standardUserDefaults]);
}

所以我知道我所追求的肯定在那里。我只知道这将是我想念的愚蠢的东西。但我看不出来,也看不出来。

谁能看到我在搞砸什么?

4

3 回答 3

5

据我所知,这是相关的代码。它可能比它需要的“更冗长”。但据我了解,从 NSUserDefaults 返回的任何内容都是不可变的,因此我必须将其重新创建为 Mutable 对象,添加需要添加的内容,然后替换 NSUserDefaults 中的对象。

一种更简单的方法是制作不可变字典的 mutableCopy,如下所示:

NSMutableDictionary *newBoards = [[immutableDict mutableCopy] autorelease];
[newBoards setObject:savedData forKey:pTitle];

此外,synchronize用于强制将用户默认值保存到磁盘。它只会影响您在 Finder 中打开 plist 时看到的内容。从应用程序的角度来看,NSUserDefaults它始终是最新的。此外,每隔一段时间就会自动保存默认值,因此您可能需要调用的唯一时间synchronize是应用程序终止时。

于 2009-12-12T15:46:02.073 回答
0

根据文档:

默认对象必须是一个属性列表,即以下实例(或集合实例的组合):NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary。

您确定要序列化的所有对象吗?看一眼NSKeyedArchiver

也看看这个问题Why NSUserDefaults failed to save NSMutableDictionary in iPhone SDK?

于 2009-12-12T14:10:10.027 回答
0

首先保存任何东西:

[[NSUserDefaults standardUserDefaults] setObject:@"Previous Value" forKey:@"Name"];

然后再次运行此代码以更新同一键的值:

[[NSUserDefaults standardUserDefaults] setObject:@"Updated Value" forKey:@"Name"];

由于性能问题,您不需要调用 [[NSUserDefaults standardUserDefaults] 同步]。只需要调用它即可。iOS 管理得很好。

您不需要删除对象。只需更新相同的密钥。它将更新该特定键的值。希望这可以帮助。

于 2017-12-07T05:09:59.763 回答