使用未在较低级别调用的编码器进行编码 object

Encode with coder not being called on lower level object

我正在更新现有应用程序以遵循 MVC 设计。我创建了一个顶级数据模型 class。在这个数据模型 class 中,我存档和取消存档一个 children 数组 (self.children)。这是 Child objects 的数组,其中包含一项 属性。项目 属性 是 BabyMilestone objects 的数组。 Child class 和 BabyMilestone class 都会自行处理 encode/decoding。 Child class 中的 objects 正在正确编码和解码。 BabyMilestone class 中的 objects 不是。编码器编码未在 BabyMilestone objects 上调用,但在 Child class.
上调用 问题:我是否需要做一些特殊的事情来编码一个 objects 的数组,它是一个 属性 的数组?欢迎任何调试建议!

顶级 DataModel class 处理 .plist

的保存和加载
@implementation DataModel
-(id)init
{
    if ((self = [super init]))
    {
          [self loadBabyMilestones];
    }
    return self;
}

/////////////Loading and Saving Methods////////////////
//Path to documentsDirectory for loading and saving the .plist file of BabyMilestone Objects
-(NSString *)documentsDirectory
{   NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths firstObject];
    return documentsDirectory;
}

-(NSString *)dataFilePath
{   return [[self documentsDirectory] stringByAppendingPathComponent:@"BabyMilestones.plist"];
    NSLog(@"The documents directory is %@", [self documentsDirectory]);
}

//Save the BabyMilestoneitems to the .plist
-(void) saveBabyMilestoneItems
{
    Child *child;
    child = [[Child alloc] init];
    child = [self.children objectAtIndex:0 ];
    NSLog(@"The length of the children array in the SAVE method is %lu", child.items.count);

    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:self.children forKey:@"Children"];
    [archiver finishEncoding];
    [data writeToFile:[self dataFilePath] atomically:YES];
    NSLog(@"In saveBabyMilestoneItems");
}

//Loading the babyMilestones data from the .plist file
-(void) loadBabyMilestones
{
    NSString *path = [self dataFilePath];
    NSLog(@"Data file path is %@", [self dataFilePath]);
    if ([[NSFileManager defaultManager]fileExistsAtPath:path])  //if file exists load self.children
    {
        NSData *data = [[NSData alloc] initWithContentsOfFile:path];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        self.children = [unarchiver decodeObjectForKey:@"Children"];
        [unarchiver finishDecoding];
        NSLog(@"In loadbabymilestones loading from file"); 
    }
    //Default list
    else {
        self.children = [[NSMutableArray alloc]initWithCapacity:2];
        Child *child;
        child = [[Child alloc] init];
        child.name = @"Test Child 1";
        [self.children addObject:child];

       child = [[Child alloc]init];
       child.name = @"Test Child 2";
       [self.children addObject:child];
       for (Child *child in self.children) {
        babyMilestone *babyItem;
        babyItem = [[babyMilestone alloc] init];
        babyItem.text = @"Arrives Home";
        babyItem.backgroundImageName = @"newText_home";
        babyItem.imageName = @"Flat_Home_Icon.png";
        babyItem.textDescription = nil;
        babyItem.highResImage = @"newText_homehighRes.jpg";
        babyItem.newItem = NO;
        babyItem.date = nil;
        babyItem.nativeItem = YES;
        babyItem.photoID = @-1;
        [child.items addObject:babyItem];
        }
    }
}

@end

BabyMilestone Class(从未调用过编码器)

#import "babyMilestone.h"
@implementation babyMilestone

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if ((self=[super init])) {
        self.textDescription = [aDecoder decodeObjectForKey:@"TextDescription"];
        self.text = [aDecoder decodeObjectForKey:@"Text"];
        self.photoID = [aDecoder decodeObjectForKey:@"PhotoID1"];
        self.imageName = [aDecoder decodeObjectForKey:@"Thumbnail"];
        self.date = [aDecoder decodeObjectForKey:@"Date"];
        self.backgroundImageName = [aDecoder decodeObjectForKey:@"BackgroundImage"];
        self.highResImage = [aDecoder decodeObjectForKey:@"HighResImage"];
        self.nativeItem = [aDecoder decodeBoolForKey:@"NativeItem"];

    }
    return self;
}

-(void) encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.textDescription forKey:@"TextDescription"];
    [aCoder encodeObject:self.text forKey:@"Text"];
    [aCoder encodeObject:self.photoID forKey:@"PhotoID1"];
    [aCoder encodeObject:self.imageName forKey:@"Thumbnail"];
    [aCoder encodeObject:self.date forKey:@"Date"];
    [aCoder encodeObject:self.backgroundImageName forKey:@"BackgroundImage"];
    [aCoder encodeObject:self.highResImage forKey: @"HighResImage"];
    [aCoder encodeBool:self.nativeItem forKey:@"NativeItem"];
    NSLog(@"In encode with coder in babymilestone.m");
}

@end

Child Class

#import "Child.h"

@implementation Child
- (id)init {    //Used when user add a new child
    if ((self = [super init])) {
        self.items = [[NSMutableArray alloc] initWithCapacity:20];
    }
    return self; }

-(id)initWithCoder:(NSCoder *)aDecoder  //Load existing children 
{
    if ((self=[super init])) {
        self.name = [aDecoder decodeObjectForKey:@"Name"];
        //self.birthday = [aDecoder decodeObjectForKey:@"Birthday"];
        NSLog(@"Init with coder being called on Child class"); 
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"Name"];
    NSLog(@"Encodewithcoder is called in the Child class");
    //[aCoder encodeObject:self.birthday forKey: @"Birthday];
}
@end

您的 Child 对象作为 babyMilestones 的守护者,负责对它们进行编码。将 [aCoder encodeObject:self.items forKey:@"Items"]; 添加到 ChildencodeWithCoder:。这样,当 Child 被告知编码时,它也会对其 babyMilestones 进行编码。