UserDefaults / KeyedArchiver Неудачи

Я работаю над приложением для домашних заданий, которое использует настраиваемые объекты Assignment для каждого задания. Я пытаюсь сохранить NSMutableArray (переданный в NSArray через initWithArray :) в standardUserDefaults, но у меня возникают проблемы с сохранением и перезагрузкой массива.

У меня есть табличное представление, из которого вы можете добавить новое назначение (которое загружает NewAssignmentViewController). Когда вы сохраняете назначение, оно возвращается в массив в AssigmentsViewController. И затем вы вызываете его каждый раз, когда загружаете UITableView, который показывает назначения.

Вот соответствующий код:

-(void)saveToUserDefaults:(NSArray*)myArray{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];

if (standardUserDefaults) {
    [standardUserDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:myArray] forKey:@"Assignments"];
    [standardUserDefaults synchronize];
    }
}

-(void)retrieveFromUserDefaults{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"Assignments"]; 
if (dataRepresentingSavedArray != nil) {
    NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
    if ([oldSavedArray count] != 0) {
        [assignments setArray:[[NSMutableArray alloc] initWithArray:oldSavedArray]];
    }
    else {
        assignments = [[NSMutableArray alloc] initWithCapacity:100];
    }
}
}
 -(void)backButtonPressed {
[self saveToUserDefaults:[[NSArray alloc] initWithArray:assignments]];
[self.navigationController popViewControllerAnimated:YES];
}

Пожалуйста помоги. Он не загружает массив, но не выдает ошибок. Будем признательны за любые советы по UserDefault или KeyedArchiver в целом.


person azban    schedule 10.12.2009    source источник


Ответы (2)


Здесь есть пара вещей:

Если я правильно вас понял, вы пытаетесь сохранить массив, содержимое которого является объектами присваивания.

Если вы хотите сериализовать эти объекты для хранения в NSUserDefaults, сами объекты Assignment должны соответствовать протоколу NSCoding путем переопределения этих методов:

- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder;

Поскольку вы не разместили код для своих объектов Assignment, не знаю, правильно ли вы это сделали или вообще. Если у вас есть, вы должны иметь возможность кодировать объект. См. Руководство по программированию архивов и сериализаций, чтобы узнать больше.

Что касается NSUserDefaults, по моему мнению, вы в основном пытаетесь сохранить там объектную модель своего приложения. Не лучшая идея. NSUserDefaults лучше всего подходит для использования с легковесными постоянными данными: основными настройками, строками, обрывками универсальных данных.

Я бы записал ваши заархивированные данные в файл и загрузил его при загрузке вашего представления.

Вот код из Начало разработки для iPhone на эту тему:

Создать архив из объекта или объектов, которые соответствуют NSCoding, относительно просто. Сначала мы создаем экземпляр NSMutableData для хранения закодированных данных, а затем создаем экземпляр NSKeyedArchiver для архивации объектов в этот экземпляр NSMutableData:

NSMutableData *data = [[NSMutableData alloc] init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

После создания обоих из них мы затем используем кодирование ключ-значение для архивации любых объектов, которые мы хотим включить в архив, например:

[archiver encodeObject:myObject forKey:@”keyValueString”];

После того, как мы закодировали все объекты, которые хотим включить, мы просто сообщаем архиватору, что все готово, записываем экземпляр NSMutableData в файловую систему и выполняем очистку памяти для наших объектов.

[archiver finishEncoding]; BOOL success = [data writeToFile:@”/path/to/archive” atomically:YES]; 
[archiver release]; 
[data release];

Чтобы восстановить объекты из архива, мы проходим аналогичный процесс. Мы создаем экземпляр NSData из файла архива и создаем NSKeyedUnarchiver для декодирования данных: NSData * data = [[NSData alloc] initWithContentsOfFile: path]; NSKeyedUnarchiver * unarchiver = [[выделение NSKeyedUnarchiver] initForReadingWithData: данные]; После этого мы читаем наши объекты из разархиватора, используя тот же ключ, который мы использовали для архивации объекта:

self.object = [unarchiver decodeObjectForKey:@”keyValueString”];

Вам также потребуется получить каталог документов приложения для сохранения и загрузки файлов.

Это чрезвычайно полезная книга, полная фрагментов кода. Глава о настойчивости может быть вам полезна. Если подумать, вы могли бы быть намного счастливее, используя Core Data для этой задачи.

person Danilo Campos    schedule 11.12.2009

Я не уверен, что это решит вашу проблему, но вам не нужно извлекать массив из значений по умолчанию как NSData. См. справочник по NSUserDefaults, и вы увидите, что массивы являются допустимыми объектами по умолчанию.

person bpapa    schedule 10.12.2009