1

我有一些存储在数组中的自定义类对象,然后将该数组存储在带有键的字典中。然后保存并在应用程序加载/重新加载时加载。

现在的问题是我似乎无法将自定义对象取出,当我加载数组时它返回为空。我必须在写入或加载数据时做错了,但我无法弄清楚到底是什么。

这是我到目前为止的代码:

CustomClass.H 文件:

#import <Foundation/Foundation.h>

@interface PersonClass : NSObject <NSCoding>

@property (nonatomic,strong) NSString *personName;
@property (nonatomic,strong) NSString *personNo;
@property (nonatomic,strong) NSString *personNotes;
@property (nonatomic) BOOL switchPersonality;
@property (nonatomic) BOOL switchChemistry;
@property (nonatomic) BOOL switchLooks;
@property (nonatomic) BOOL switchHumour;
@property (nonatomic) int personRating;
@property (nonatomic,strong) NSNumber *personRecord;


- (id)initWithName:(NSString *)iPersonName PersonNo:(NSString *)iPersonNo PersonNotes:(NSString *)iPersonNotes SwitchChemistry:(BOOL *)iSwitchChemistry SwitchHumour:(BOOL *)iSwitchHumour SwitchLooks:(BOOL *)iSwitchLooks SwitchPersonality:(BOOL *)iSwitchPersonality PersonRating:(int *)iPersonRating PersonRecord:(NSNumber *)iPersonRecord;

@end

自定义 Class.M 文件:

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

    [aCoder encodeObject:personName forKey:@"pName"];
    [aCoder encodeObject:personNo forKey:@"pNo"];
    [aCoder encodeObject:personNotes forKey:@"pNotes"];
    [aCoder encodeInt:personRating forKey:@"pRating"];
    [aCoder encodeObject:personRecord forKey:@"pRecord"];
    [aCoder encodeBool:switchChemistry forKey:@"sChemistry"];
    [aCoder encodeBool:switchHumour forKey:@"sHumour"];
    [aCoder encodeBool:switchLooks forKey:@"sLooks"];
    [aCoder encodeBool:switchPersonality forKey:@"sPersonality"];

}

-(id)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super init]){

        self.personName = [aDecoder decodeObjectForKey:@"pName"];
        self.personNo = [aDecoder decodeObjectForKey:@"pNo"];
        self.personNotes = [aDecoder decodeObjectForKey:@"pNotes"];
        self.personRating = [aDecoder decodeIntForKey:@"pRating"];
        self.personRecord = [aDecoder decodeObjectForKey:@"pRecord"];
        self.switchChemistry = [aDecoder decodeBoolForKey:@"sChemistry"];
        self.switchHumour = [aDecoder decodeBoolForKey:@"sHumour"];
        self.switchLooks = [aDecoder decodeBoolForKey:@"sLooks"];
        self.switchPersonality = [aDecoder decodeBoolForKey:@"sPersonality"];
    }

    return self;
}

保存方法:

- (void)saveData{

    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"data.plist"];
    NSLog(@"PList Path %@",plistPath);
    //new array
    NSMutableArray *newEntries = [[NSMutableArray alloc]init];
    NSLog(@"NEW ENTRIES BEFORE %@",newEntries);
    for (PersonClass *person in peopleEntries) {

        //encode the object
        [NSKeyedArchiver archivedDataWithRootObject:person];
        // add the object to the entries 
        [newEntries addObject:person];
    }
    NSLog(@"NEW ENTRIES AFTER %@",newEntries);
    [newEntries writeToFile:plistPath atomically:YES];
    // create dictionary with arrays and their corresponding keys
    NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSMutableArray arrayWithObjects:newEntries, recordId, nil] forKeys:[NSMutableArray arrayWithObjects: @"peopleEntries",@"recordId", nil]];

    NSLog(@"DICTIONARY IS IN SAVE %@",plistDict);

    NSString *error = nil;

    // check if plistData exists
    if(plistDict)
    {
        // write plistData to our Data.plist file
        [plistDict writeToFile:plistPath atomically:YES];
    }
    else
    {
        NSLog(@"Error in saveData: %@", error);
    }
    NSLog(@"Save RUN");
}

加载方法:

- (void)loadData{

        // get paths from root direcory
        NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
        // get documents path
        NSString *documentsPath = [paths objectAtIndex:0];
        // get the path to our Data/plist file
        NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"data.plist"];
         NSLog(@"PList Path %@",plistPath);

        // check to see if data.plist exists in documents
        if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
        {
            // return without loading
            NSLog(@"RETURNING");
            return;
        }

        // get saved dictionary
        NSDictionary *dictionaryTemp = [[NSDictionary alloc]initWithContentsOfFile:plistPath];
        NSLog(@"DICTIONARY IS LOAD %@",dictionaryTemp);
        if (!dictionaryTemp)
        {
            NSLog(@"Error reading plist:");
        }
        // temporary array
        NSMutableArray *holderOne = [dictionaryTemp objectForKey:@"peopleEntries"];

        // array to be populated
        NSMutableArray *holderTwo = [[NSMutableArray alloc]init];
        NSLog(@"HOLDER ONE IS BEFORE %@",holderOne);
        NSLog(@"HOLDER TWO IS BEFORE %@",holderTwo);
        // go through the array and pull out person classes
        for (NSData *person in holderOne) {

            // temp array
            NSData *entry = [holderOne objectAtIndex:person]; // check the object at index might be an issue???
            NSLog(@"ENTRY IS %@",entry);
            //deencode the object
            [NSKeyedUnarchiver unarchiveObjectWithData:entry];
            // add the object to the entries
            [holderTwo addObject:entry];
        }
        NSLog(@"HOLDER ONE IS AFTER %@",holderOne);
        NSLog(@"HOLDER TWO IS AFTER %@",holderTwo);
        // assign values
        peopleEntries = [NSMutableArray arrayWithArray:holderTwo];
        NSLog(@"DICTIONARY IS AFTER ADDING %@",dictionaryTemp);
        recordId = [NSNumber numberWithInt:[[dictionaryTemp objectForKey:@"recordId"]integerValue]];
        NSLog(@"recordId is %@",recordId);
        NSLog(@"LOAD RUN");
    }
4

1 回答 1

0

好的,我终于发现了这个问题,我从 NSObject 子类扩展了我的类,它没有实现 NSCoder 协议,所以我以不正确的方式编码和解码我的对象。它应该通过以下方式完成:

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.personName = [decoder decodeObjectForKey:@"pName"];
        self.personNo = [decoder decodeObjectForKey:@"pNo"];
        self.personNotes = [decoder decodeObjectForKey:@"pNotes"];
        self.personRating = [decoder decodeObjectForKey:@"pRating"];
        self.switchChemistry = [decoder decodeBoolForKey:@"sChemistry"];
        self.switchHumour = [decoder decodeBoolForKey:@"sHumour"];
        self.switchLooks = [decoder decodeBoolForKey:@"sLooks"];
        self.switchPersonality = [decoder decodeBoolForKey:@"sPersonality"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:personName forKey:@"pName"];
    [encoder encodeObject:personNo forKey:@"pNo"];
    [encoder encodeObject:personNotes forKey:@"pNotes"];
    [encoder encodeObject:personRating forKey:@"pRating"];
    [encoder encodeBool:switchChemistry forKey:@"sChemistry"];
    [encoder encodeBool:switchHumour forKey:@"sHumour"];
    [encoder encodeBool:switchLooks forKey:@"sLooks"];
    [encoder encodeBool:switchPersonality forKey:@"sPersonality"];
}

然后将这些对象添加到一个数组中,我循环遍历数组中的每个对象并进行解码。这是不正确的,您可以简单地使用 te 对象对整个数组进行编码或解码,如下所示:

解码:

NSData *peopleData;
peopleEntries = [NSKeyedUnarchiver unarchiveObjectWithData:peopleData]; 

编码:

NSMutableArray *peopleEntries;
NSData *personData = [NSKeyedArchiver archivedDataWithRootObject:[[GlobalData sharedGlobalData]peopleEntries]];
于 2013-07-10T20:34:37.437 回答