несогласованное поведение по умолчанию (NSUserDefaults) в настройках iPhone simulator по умолчанию

StackOverflow https://stackoverflow.com/questions/475367

  •  19-08-2019
  •  | 
  •  

Вопрос

Я сталкивался с очень противоречивыми результатами при разработке приложения для 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];
}

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Чтобы загрузить старые значения из значений по умолчанию.

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

Другие советы

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

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

  1. Напишите метод, который преобразует ваш объект в представление plist и обратно.Другими словами, метод для создания NSDictionary из вашего объекта и другой метод для инициализации объекта с помощью NSDictionary.Вы также можете сохранить его как NSArray или NSString .
  2. Заставьте ваш объект реализовать протокол NSCoding, а затем используйте NSKeyedArchiver для преобразования объекта в объект NSData и NSKeyedUnarchiver для его обратного преобразования.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top