2013-04-23 3 views
3

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

*** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '(
    "<Item: 0x1e86e380>", 
    "<Item: 0x1e86fd60>", 
    "<Item: 0x1e86fda0>", 
    "<Item: 0x1e86fde0>", 
    "<Item: 0x1e86fe10>" 
)' of class '__NSArrayM'. Note that dictionaries and arrays in property lists must also contain only property values. 
[unknown][unknown][unknown][unknown][unknown](gdb) 

Почему ??

Вот мой код:

Это моя модель. Он имеет NSStrings, NSNumbers и NSMutableArrays:

- (void)encodeWithCoder:(NSCoder *)encoder 
{ 
    [encoder encodeObject: self.title forKey:@"title"]; 
    [encoder encodeObject: self.desc forKey:@"desc"]; 
    [encoder encodeObject: (NSNumber*) self.day forKey:@"day"]; 
    [encoder encodeObject: self.images forKey:@"images"]; 
} 

- (id)initWithCoder:(NSCoder *)decoder 
{ 
    self = [super init]; 
    if(self != nil) 
    { 
     self.title = [decoder decodeObjectForKey: @"title"]; 
     self.desc = [decoder decodeObjectForKey: @"desc"]; 
     self.day = [decoder decodeObjectForKey: @"day"]; 
     self.images = [decoder decodeObjectForKey: @"images"]; 

    } 
    return self; 
} 

Это в DidFinishLaunching методе AppDelegate в:

if([[NSUserDefaults standardUserDefaults] objectForKey:@"savedData"] == nil) 
{ 
    items = [[NSMutableArray alloc] init]; 

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"items" ofType:@"json"]; 
    NSString *contents = [NSString stringWithContentsOfFile: filePath encoding: NSUTF8StringEncoding error: nil]; 
    SBJsonParser *jsonParser = [[SBJsonParser alloc] init]; 
    NSMutableDictionary *json = [jsonParser objectWithString: contents]; 
    jsonParser = nil; 
    items = json[@"item"]; 

    for(NSDictionary *itemDict in items) 
    { 

     Item *item = [[Item alloc] init]; 

     item.title = [itemDict valueForKey:@"title"]; 
     item.desc = [itemDict valueForKey:@"description"]; 
     item.day = [itemDict valueForKey:@"day"]; 
     item.images = [itemDict valueForKey: @"images"]; 

     [items addObject: item]; 

    }  
} 
else 
{ 

    NSData *decodedObject = [userDefault objectForKey: [NSString stringWithFormat:@"savedData"]]; 
    NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: decodedObject]; 


    items = [decodedArray mutableCopy]; 

} 

И это я имею в AppWillTerminate:

userDefault = [NSUserDefaults standardUserDefaults]; 
    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject: items]; 
    [userDefault setObject: encodedObject forKey:[NSString stringWithFormat:@"savedData"]]; 
+0

Я не думаю, что это исключение исходит из кода, который вы указали. Добавить контрольную точку исключения в Xcode. Я подозреваю, что вы используете 'setObject: forKey:' с массивом объектов Item (объектов, не относящихся к объектам) в другом месте вашего проекта. – omz

+0

да. когда я удаляю этот код, ошибка исчезает .. – Jojo

+0

вы можете хранить только встроенные значения типа объекта в NSUserDefault, если вы попытаетесь сохранить Custom (User Defined Object), это приведет к возникновению ошибки, поэтому, пожалуйста, храните встроенные объекты –

ответ

1

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

EDIT

В предыдущем абзаце я сказал, что каталог Поддержка приложений не следует использовать для данных, которые будут изменяться. Я не могу найти ничего, чтобы поддержать это. Собственная документация Apple гласит, что «где ваше приложение хранит файлы любого типа, поддерживающие приложение, но не требуемые для запуска приложения», что данные пользователя не должны там храниться и что каждое приложение должно создавать и поддерживать свои собственные внутри него, а не писать на верхний уровень. Совсем не определен, где я взял этот кусочек фантастики и сожалею, что увековечил его.

END EDIT

Это, как говорится, когда компилятор жалуется на «значение неимущественного (ов)», что означает, что вы пытаетесь написать что-то, что не является NSArray,NSDictionary,NSString,NSData,NSDate или NSNumber.

Вы правы, что ваши собственные объекты должны использовать NSKeyedArchiver и NSKeyedUnarchiver. Но только потому, что вы применяете методы NSCoding в объекте модели, это не меняет того факта, что это не значение списка свойств.

Что вам нужно сделать, это использовать NSKeyedArchiverдо, вы пытаетесь сохранить каждый из ваших объектов. Это создает экземпляр NSData, который может быть сохранен как объект списка свойств.

+0

Почему бы вам избегайте папки поддержки приложений? – omz

 Смежные вопросы

  • Нет связанных вопросов^_^