2012-04-11 3 views
0

закодировать так:NSKeyedUnarchiver не может декодировать обратно мой сохраненный объект

NSMutableData *data = [[NSMutableData alloc] init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];   
[archiver encodeObject:data forKey:@"Object"]; 
[archiver finishEncoding]; 

Затем, после получения сохраненного файла с диска я пытаюсь расшифровать так:

Object *object = (Object*)[unarchiver decodeObjectForKey:@"Object"]; 

Проблема заключается в том, что это никогда не декодируется обратно в тип Object *. Он остается NSMutableData. Поэтому, когда я пытаюсь получить доступ к некоторому свойству объекта типа «object.name», я получаю - [NSConcreteMutableData name]: нераспознанный селектор, отправленный экземпляру 0x2c8510 '.

Я следовал за руководством Рэя Вендерлиха http://www.raywenderlich.com/1914/how-to-save-your-app-data-with-nscoding-and-nsfilemanager. Несмотря на то, что его код работает, у меня нет. Поэтому, после дня, когда я воюю с этим, я прошу о помощи.

ответ

2

В учебнике вы цитируете использует свойство «данные» на классе, а также переменные называются «данные» в методе сейва. Он записывает свойство «_data» (или, по крайней мере, синтезированную переменную экземпляра _data) в «данные» объекта NSMutableData, когда он вызывает encodeObject :. Это немного запутанно, потому что он использует одно и то же имя для двух разных вещей.

Вы, otoh, создаете ivar с именем «данные», а затем отправляете его в encodeObject :. Вы никогда не получаете доступ к свойству Object *, просто записывая пустую NSMutableData в NSMutableData. Разница заключается в отсутствии подчеркивания, но есть лучший способ imho.

Я рекомендую вам переименовать свойство данных, которые вы пытаетесь кодировать, скажем, «информация» (или, может быть, что-то более информативное, например «фондовыецены» или «todaysWeather» или любые данные, хранящиеся этим классом)

@property Object* info; 

и переименовать аксессор надлежащим образом (при условии, что вы делаете вещи, как он сделал)

, а затем написать:

[archiver encodeObject:self.info forKey:@"Object"] 

Две вещи happeni здесь для вашей пользы в качестве разработчика: вы используете разные имена для кодируемых данных и информацию, которую вы кодируете, и вы явно пишете в коде, в котором говорится, что вы обращаетесь к информационному свойству своего класса, а не некоторой локальной переменной. Оба из них упростят вашу жизнь через 6 месяцев после просмотра этого кода.

1

Это потому, что вы кодируете data не object. Измените эту строку:

[archiver encodeObject:data forKey:@"Object"]; 

к этому

[archiver encodeObject:object forKey:@"Object"]; 
Смежные вопросы