поведение по умолчанию (NSUserDefaults) в настройках симулятора iPhone - PullRequest
5 голосов
/ 24 января 2009

Я получал очень противоречивые результаты при разработке приложения для iPhone и попытке сохранить настройки с помощью стандартного механизма NSUserDefaults. Я использую код почти прямо из книги разработчиков iPhone от Эрики Садун (кстати, фантастическая книга), она выглядит так:

(void) updateDefaults
{
    NSMutableArray *spells =  [[NSMutableArray alloc] init];
    NSMutableArray *locs = [[NSMutableArray alloc] init];

    for (DragView *dv in [boardView subviews]) 
    {
        [spells addObject:[dv whichSpell]];
        [locs addObject:NSStringFromCGRect([dv frame])]; 
    }

    [[NSUserDefaults standardUserDefaults] setObject:spells forKey:@"spells"];
    [[NSUserDefaults standardUserDefaults] setObject:locs forKey:@"locs"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    [spells release];
    [locs release];
}

Значения сохраняются, иногда ... и восстанавливаются, иногда. Я не могу получить точную информацию о том, что работает или не работает.

У кого-нибудь еще есть подобный опыт? Любые предложения о том, что может заставить его работать? Является ли метод синхронизации лучшим способом заставить запись на диск и сохранить значения, или есть что-то лучшее (как для производства, так и для симулятора).

Спасибо Райан

Ответы [ 2 ]

2 голосов
/ 04 февраля 2009

В Mac OS X и, возможно, также в iPhone OS база данных по умолчанию может содержать только объекты списка свойств: NSString, NSNumber, NSArray, NSDictionary и NSData.

Из вашего фрагмента кода неясно, к какому типу относится заклинание, но если оно не является одним из вышеперечисленных, оно не будет сохранено в базе данных по умолчанию. Ваши варианты:

  1. Напишите метод, который преобразует ваш объект в представление plist и из него. Другими словами, метод для создания NSDictionary из вашего объекта и другой метод для инициализации объекта с использованием NSDictionary. Вы также можете сохранить его как NSArray или NSString.
  2. Заставьте ваш объект реализовать протокол NSCoding и затем использовать NSKeyedArchiver для преобразования объекта в объект NSData и NSKeyedUnarchiver для его преобразования обратно.
2 голосов
/ 24 января 2009

Вы должны использовать NSKeyedArchiver для сохранения ваших массивов, например:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:spells] forKey:@"spells"];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:locs] forKey:@"locs"];
[[NSUserDefaults standardUserDefaults] synchronize];

Вы также должны убедиться, что ваш класс заклинаний реализует протокол NSCoding (encodeWithCoder: и initWithCoder :), если это пользовательский класс. Похоже, ваши locs - это NSStrings, которые будут прекрасно архивироваться.

Вам также нужно будет сделать что-то вроде

NSData *dataRepresentingSavedSpells = [currentDefaults objectForKey:@"spells"];
if (dataRepresentingSavedSpells != nil)
{
    NSArray *oldSpells = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedSpells];
}

Для загрузки старых значений по умолчанию.

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

...