尝试将非属性列表对象设置为NSUserDefault

尝试将非属性列表对象设置为NSUserDefault

我以为我知道是什么导致了这个错误,但我似乎不知道我做错了什么。

下面是我得到的完整错误消息:

Attempt to set a non-property-list object (
   "<BC_Person: 0x8f3c140>"
) as an NSUserDefaults value for key personDataArray

我有一个Person类,我认为该类符合NSCoding协议,在我的Person类中有这两种方法:

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.personsName forKey:@"BCPersonsName"];
    [coder encodeObject:self.personsBills forKey:@"BCPersonsBillsArray"];}- (id)initWithCoder:(NSCoder *)coder {
    self = [super init];
    if (self) {
        self.personsName = [coder decodeObjectForKey:@"BCPersonsName"];
        self.personsBills = [coder decodeObjectForKey:@"BCPersonsBillsArray"];
    }
    return self;}

在应用程序的某个时候,NSStringBC_PersonClass设置好了,我有一个DataSave类,我认为该类正在处理BC_PersonClass..下面是我从DataSave班级:

- (void)savePersonArrayData:(BC_Person *)personObject{
   // NSLog(@"name of the person %@", personObject.personsName);

    [mutableDataArray addObject:personObject];

    // set the temp array to the mutableData array
    tempMuteArray = [NSMutableArray arrayWithArray:mutableDataArray];

    // save the person object as nsData
    NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];

    // first add the person object to the mutable array
    [tempMuteArray addObject:personEncodedObject];

    // NSLog(@"Objects in the array %lu", (unsigned long)mutableDataArray.count);

    // now we set that data array to the mutable array for saving
    dataArray = [[NSArray alloc] initWithArray:mutableDataArray];
    //dataArray = [NSArray arrayWithArray:mutableDataArray];

    // save the object to NS User Defaults
    NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
    [userData setObject:dataArray forKey:@"personDataArray"];
    [userData synchronize];}

我希望这是足够的代码给你一个想法,我想做什么。同样,我知道我的问题在于如何在BC_Person类中编码我的属性,我只是不知道自己做错了什么。

谢谢你的帮助!


明月笑刀无情
浏览 512回答 3
3回答

蓝山帝景

您发布的代码试图将自定义对象数组保存到NSUserDefaults..你不能那样做。实现NSCoding方法没什么用。你只能储存这样的东西NSArray,&nbsp;NSDictionary,&nbsp;NSString,&nbsp;NSData,&nbsp;NSNumber,和NSDate在……里面NSUserDefaults.您需要将对象转换为NSData(就像一些代码中的代码),并将其存储起来。NSData在……里面NSUserDefaults..你甚至可以储存NSArray的NSData如果你需要的话。当您读取回数组时,需要将NSData为了找回你的BC_Person物品。也许你想要这样:-&nbsp;(void)savePersonArrayData:(BC_Person&nbsp;*)personObject&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;[mutableDataArray&nbsp;addObject:personObject]; &nbsp;&nbsp;&nbsp;&nbsp;NSMutableArray&nbsp;*archiveArray&nbsp;=&nbsp;[NSMutableArray&nbsp;arrayWithCapacity:mutableDataArray.count]; &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(BC_Person&nbsp;*personObject&nbsp;in&nbsp;mutableDataArray)&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSData&nbsp;*personEncodedObject&nbsp;=&nbsp;[NSKeyedArchiver&nbsp;archivedDataWithRootObject:personObject]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[archiveArray&nbsp;addObject:personEncodedObject]; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;NSUserDefaults&nbsp;*userData&nbsp;=&nbsp;[NSUserDefaults&nbsp;standardUserDefaults]; &nbsp;&nbsp;&nbsp;&nbsp;[userData&nbsp;setObject:archiveArray&nbsp;forKey:@"personDataArray"];}

慕少森

在我看来,自己运行数组并将对象编码到NSData中是相当浪费的。你的错误BC_Person is a non-property-list object告诉您框架不知道如何序列化您的Person对象。因此,所需要的只是确保您的Person对象符合NSCoding,然后您可以简单地将您的自定义对象数组转换为NSData,并将其存储为默认值。这里是一个游乐场:编辑*写信给NSUserDefaults在Xcode 7上出现故障,因此操场将存档为数据,然后返回并打印输出。如果它在以后的某个点固定,则包含UserDefault步骤。//:&nbsp;Playground&nbsp;-&nbsp;noun:&nbsp;a&nbsp;place&nbsp;where&nbsp;people&nbsp;can&nbsp;playimport&nbsp;Foundationclass&nbsp;Person:&nbsp;NSObject,&nbsp;NSCoding&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;surname:&nbsp;String &nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;firstname:&nbsp;String &nbsp;&nbsp;&nbsp;&nbsp;required&nbsp;init(firstname:String,&nbsp;surname:String)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.firstname&nbsp;=&nbsp;firstname &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.surname&nbsp;=&nbsp;surname &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.init() &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//MARK:&nbsp;-&nbsp;NSCoding&nbsp;- &nbsp;&nbsp;&nbsp;&nbsp;required&nbsp;init(coder&nbsp;aDecoder:&nbsp;NSCoder)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;surname&nbsp;=&nbsp;aDecoder.decodeObjectForKey("surname")&nbsp;as!&nbsp;String &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstname&nbsp;=&nbsp;aDecoder.decodeObjectForKey("firstname")&nbsp;as!&nbsp;String &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;func&nbsp;encodeWithCoder(aCoder:&nbsp;NSCoder)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aCoder.encodeObject(firstname,&nbsp;forKey:&nbsp;"firstname") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aCoder.encodeObject(surname,&nbsp;forKey:&nbsp;"surname") &nbsp;&nbsp;&nbsp;&nbsp;}}//:&nbsp;###&nbsp;Now&nbsp;lets&nbsp;define&nbsp;a&nbsp;function&nbsp;to&nbsp;convert&nbsp;our&nbsp;array&nbsp;to&nbsp;NSDatafunc&nbsp;archivePeople(people:[Person])&nbsp;->&nbsp;NSData&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;archivedObject&nbsp;=&nbsp;NSKeyedArchiver.archivedDataWithRootObject(people&nbsp;as&nbsp;NSArray) &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;archivedObject}//:&nbsp;###&nbsp;Create&nbsp;some&nbsp;peoplelet&nbsp;people&nbsp;=&nbsp;[Person(firstname:&nbsp;"johnny",&nbsp;surname:"appleseed"),Person(firstname:&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;"peter",&nbsp;surname:&nbsp;"mill")]//:&nbsp;###&nbsp;Archive&nbsp;our&nbsp;people&nbsp;to&nbsp;NSDatalet&nbsp;peopleData&nbsp;=&nbsp;archivePeople(people)if&nbsp;let&nbsp;unarchivedPeople&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSKeyedUnarchiver.unarchiveObjectWithData(peopleData)&nbsp;as?&nbsp;[Person]&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;person&nbsp;in&nbsp;unarchivedPeople&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("\(person.firstname),&nbsp;you&nbsp;have&nbsp;been&nbsp;unarchived") &nbsp;&nbsp;&nbsp;&nbsp;}}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;print("Failed&nbsp;to&nbsp;unarchive&nbsp;people")}//:&nbsp;###&nbsp;Lets&nbsp;try&nbsp;use&nbsp;NSUserDefaultslet&nbsp;UserDefaultsPeopleKey&nbsp;=&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;"peoplekey"func&nbsp;savePeople(people:[Person])&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;archivedObject&nbsp;=&nbsp;archivePeople(people) &nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;defaults&nbsp;=&nbsp;NSUserDefaults.standardUserDefaults() &nbsp;&nbsp;&nbsp;&nbsp;defaults.setObject(archivedObject,&nbsp;forKey:&nbsp;UserDefaultsPeopleKey) &nbsp;&nbsp;&nbsp;&nbsp;defaults.synchronize()}func&nbsp;retrievePeople()&nbsp;->&nbsp;[Person]?&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;let&nbsp;unarchivedObject&nbsp;=&nbsp;NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsPeopleKey)&nbsp;as?&nbsp;NSData&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;NSKeyedUnarchiver.unarchiveObjectWithData(unarchivedObject)&nbsp;as?&nbsp;[Person] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;nil}if&nbsp;let&nbsp;retrievedPeople&nbsp;=&nbsp;retrievePeople()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;person&nbsp;in&nbsp;retrievedPeople&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("\(person.firstname),&nbsp;you&nbsp;have&nbsp;been&nbsp;unarchived") &nbsp;&nbsp;&nbsp;&nbsp;}}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;print("Writing&nbsp;to&nbsp;UserDefaults&nbsp;is&nbsp;still&nbsp;broken&nbsp;in&nbsp;playgrounds")}而Voila,您已经将一个自定义对象数组存储到NSUserDefault中

慕沐林林

拯救:NSUserDefaults&nbsp;*currentDefaults&nbsp;=&nbsp;[NSUserDefaults&nbsp;standardUserDefaults];NSData&nbsp;*data&nbsp;=&nbsp;[NSKeyedArchiver&nbsp;archivedDataWithRootObject:yourObject]; [currentDefaults&nbsp;setObject:data&nbsp;forKey:@"yourKeyName"];得到:NSData&nbsp;*data&nbsp;=&nbsp;[currentDefaults&nbsp;objectForKey:@"yourKeyName"];yourObjectType&nbsp;*&nbsp;token&nbsp;=&nbsp;[NSKeyedUnarchiver&nbsp;unarchiveObjectWithData:data];移除[currentDefaults&nbsp;removeObjectForKey:@"yourKeyName"];
打开App,查看更多内容
随时随地看视频慕课网APP