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

OK、ついに問題を発見しました。NSCoderプロトコルを実装していないNSObjectサブクラスからクラスを拡張していたため、オブジェクトを誤った方法でエンコードおよびデコードしていました。次の方法で行う必要があります。

- (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"];
}

次に、これらのオブジェクトが配列に追加され、配列内の各オブジェクトをループしてデコードしていました。これは正しくありませんでした。配列全体をオブジェクトで単純にエンコードまたはデコードできます。

デコード:

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

エンコード:

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