开发者

How to update an NSUserDefault

I have the following code which should update a value in NSUserDefaults:

- (id) c开发者_Go百科reateBoardWithTitle:(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;

}

As far as I can tell, that's the pertinent code. It's probably "wordier" than it needs to be perhaps. But as I understand it, anything returned from NSUserDefaults will be immutable, so I have to recreate it as a Mutable object, add what needs adding then replace the object in NSUserDefaults. And I think what I'm trying above should work.

the output for 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" is just a test entry and is set in the AppDelegate.m file like this:

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

So I know that what I'm after is definitely there. I just know this is going to be something stupid that I'm missing. But I can't see it or figure it out.

Can anyone see what I'm messing up?


As far as I can tell, that's the pertinent code. It's probably "wordier" than it needs to be perhaps. But as I understand it, anything returned from NSUserDefaults will be immutable, so I have to recreate it as a Mutable object, add what needs adding then replace the object in NSUserDefaults.

An easier way is to make a mutableCopy of the immutable dictionary like this:

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

Also, synchronize is used to force saving the user defaults to disk. It's only influencing what you see when you open the plist in the Finder. From the perspective of the application NSUserDefaults is always up-to-date. Also, the defaults are saved automatically every little while, so the only time you likely ever need to call synchronize is when your application terminates.


According to the docs:

A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary.

Are you sure about all the objects you are trying to serialise? Take a look at NSKeyedArchiver

Also look at this question Why NSUserDefaults failed to save NSMutableDictionary in iPhone SDK?


At first save anything:

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

Then run this code again to update value of the same key:

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

you dont need to call [[NSUserDefaults standardUserDefaults] synchronize] due to performance issue.call it only it required. iOS manages it well.

You dont need to remove object. Just update the same key. It will update the Value of that particular key. Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜