Как обновить NSUserDefault

У меня есть следующий код, который должен обновить значение в 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, будет неизменным, поэтому мне нужно воссоздать его как изменяемый объект, добавить то, что нужно добавить, а затем заменить объект в 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]);
}

Так что я знаю, что то, что мне нужно, определенно там. Я просто знаю, что это будет что-то глупое, чего мне не хватает. Но я не могу этого увидеть или понять.

Кто-нибудь может увидеть, что я напутал?


person gargantuan    schedule 12.12.2009    source источник
comment
Не делайте objectForKey:@"BlockDepotLeaderboards". Вы понятия не имеете, каким на самом деле будет возвращаемый объект. Вместо этого используйте -dictionaryForKey: и обработайте случай, когда он равен нулю, создав новый словарь.   -  person Mike Abdullah    schedule 12.12.2009
comment
если вы получаете доступ к значениям из NSUserDefaults, вы должны либо использовать dictionForKey:, либо ввести объект в словарь   -  person Madhup Singh Yadav    schedule 13.12.2009


Ответы (3)


Насколько я могу судить, это соответствующий код. Возможно, это «более многословно», чем должно быть. Но, насколько я понимаю, все, что возвращается из NSUserDefaults, будет неизменным, поэтому мне нужно воссоздать его как изменяемый объект, добавить то, что нужно добавить, а затем заменить объект в NSUserDefaults.

Более простой способ - сделать mutableCopy неизменяемого словаря следующим образом:

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

Кроме того, synchronize используется для принудительного сохранения пользовательских настроек по умолчанию на диск. Это влияет только на то, что вы видите, когда открываете plist в Finder. С точки зрения приложения NSUserDefaults всегда актуально. Кроме того, значения по умолчанию автоматически сохраняются через некоторое время, поэтому единственный раз, когда вам, вероятно, понадобится вызывать synchronize, это когда ваше приложение завершает работу.

person Adrian    schedule 12.12.2009

Согласно документам:

Объект по умолчанию должен быть списком свойств, то есть экземпляром (или для коллекций комбинацией экземпляров): NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary.

Вы уверены насчет всех объектов, которые пытаетесь сериализовать? Взгляните на NSKeyedArchiver

Также посмотрите на этот вопрос Почему NSUserDefaults не удалось сохранить NSMutableDictionary в iPhone SDK ?

person lyonanderson    schedule 12.12.2009
comment
Я использую NSKeyedArchiver в другом месте для чего-то другого. Этот проект в первую очередь является проектом самообучения, поэтому я хочу добиться этого. Но я думал о том же; Насколько я могу судить, я пытаюсь сохранить NSDictionary с двумя NSString и NSarray, который содержит 10 NSDictionary, содержащих два NSString и 1 NSNUmber. Но я вернусь и трижды проверю. - person gargantuan; 12.12.2009

Сначала сохраните что-нибудь:

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

Затем снова запустите этот код, чтобы обновить значение того же ключа:

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

вам не нужно вызывать [[NSUserDefaults standardUserDefaults] synchronize] из-за проблем с производительностью. iOS справляется с этим хорошо.

Вам не нужно удалять объект. Просто обновите тот же ключ. Он обновит значение этого конкретного ключа. Надеюсь это поможет.

person Raj Aryan    schedule 07.12.2017