NSUserDefaults NSObject с NSArray обект

Опитвам се да запазя обект в NSUserDefaults, преминах през много въпроси на този сайт, но не можах да разреша проблема, моят NSObject има NSMutableArray на друг обект. като тук основният обект е HotelDC и има масив, който "съдържа" масив от FeactureDC обекта.

Ето моят код:

- (id)initWithCoder:(NSCoder *)decoder {
self = [[HotelDC alloc] init];
if (self != nil) {

    self.hotel_id = [decoder decodeIntegerForKey:@"hotel_id"];
    self.name = [decoder decodeObjectForKey:@"name"];
    self.features = [decoder decodeObjectForKey:@"features"];

}
return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {

[encoder encodeInt:hotel_id forKey:@"hotel_id"];
[encoder encodeObject:name forKey:@"name"];
[encoder encodeObject:features forKey:@"features"];//its a mutable array
}

как да го запазя и изтегля?? Получавам грешка като

 Attempt to insert non-property value '<HotelDC: 0xa600fe0>' of class 'HotelDC'. 
 Note that dictionaries and arrays in property lists must also contain only property values.

Решение:

//Setting
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:hotelObjSelected];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:@"selectHotelObject"];

[[NSUserDefaults standardUserDefaults] synchronize];

// retrieving
NSData *data = [defaults objectForKey:@"selectHotelObject"];
hotelObjSelected = [NSKeyedUnarchiver unarchiveObjectWithData:data];

person Raheel Sadiq    schedule 04.02.2013    source източник
comment
HotelDC прилага NSCoding, но какво да кажем за FeatureDC?   -  person Firoze Lafeer    schedule 04.02.2013
comment
@FirozeLafeer той също така прилага nscoding   -  person Raheel Sadiq    schedule 04.02.2013


Отговори (4)


NSUserDefaults е подкрепено от списък със свойства. Уви, списъците със свойства не могат да съдържат сериализирани обекти. Цитирам от ръководството:

Обектът по подразбиране трябва да бъде списък със свойства, тоест екземпляр на (или за колекции комбинация от екземпляри на): NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary. Ако искате да съхранявате друг тип обект, обикновено трябва да го архивирате, за да създадете екземпляр на NSData

Ще трябва да създадете свой собствен сериализиран файл с данни за директно записване на обекта или да сериализирате обектите като един от разрешените типове. Досадно е, че NSUserDefaults не извиква encodeWithCoder - той просто проверява типа обект, предаден на setObject:forKey:. Най-добрият залог е или сами да сериализирате полетата на HotelDC, или да архивирате обекта в екземпляр NSData и да го съхраните.

person Adam Wright    schedule 04.02.2013
comment
Както споменах там NSArray, ако направя своя NSMutableArray в NSArray ще работи ли? - person Raheel Sadiq; 04.02.2013
comment
Това не е NSMutableArray (тъй като това е NSArray, ще се сериализира). Проблемът е, че в даден момент се обаждате на [nsUD setObject:someHotelDC forKey:aKey]. NSUserDefaults е твърде глупаво, за да се извика методът encodeObject - той просто проверява дали типът на someHotelDC е известен тип списък със свойства. Не е, така че хвърля изключението. Трябва да приключите екземпляра HotelDC в тип списък със свойства, преди да се опитате да го добавите към списъка със свойства (кодирането като NSData първо ще работи). - person Adam Wright; 04.02.2013

Направих това по следния начин. Проверете го. Кодът по-долу е във for цикъл.

 NSMutableArray *newEventArray = [[NSMutableArray alloc] init];
                    [newEventArray addObject:title];
                    [newEventArray addObject:alarmDate];

 NSArray *iCalAlarmArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"alarmList"];
                    if(iCalAlarmArray == nil || [iCalAlarmArray count] <= 0)
                    {
                        iCalAlarmArray = [[NSMutableArray alloc] init];
                    }

iCalAlarmArray = [iCalAlarmArray arrayByAddingObject:newEventArray];

[[NSUserDefaults standardUserDefaults] setObject:iCalAlarmArray forKey:@"alarmList"];

[[NSUserDefaults standardUserDefaults] synchronize];

Нека това ви помогне.

person python    schedule 04.02.2013

трябва да напишете подобни методи за кодиране и декодиране в FeatureDC и да ги съхраните в масив и след това да кодирате тук.

person Nareshkumar    schedule 04.02.2013
comment
да, правя същото кодиране и декодиране, имате предвид, че съхранявам обект в масив и го запазвам като NSData *data = [NSKeyedArchiver archivedDataWithRootObject:hotelObj]; - person Raheel Sadiq; 04.02.2013

Обектът по подразбиране трябва да бъде списък със свойства, тоест екземпляр на (или за колекции комбинация от екземпляри на): NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary. Ако искате да съхранявате друг тип обект, обикновено трябва да го архивирате, за да създадете екземпляр на NSData

person Roby    schedule 03.05.2016