使用未在较低级别对象上调用的编码器进行编码

时间:2015-07-27 13:52:08

标签: ios objective-c nscoding

我正在更新现有应用以遵循MVC设计。我创建了一个顶级数据Model类。在这个dataModel类中,我存档并解压缩子数组(self.children)。这是具有items属性的Child对象数组。 items属性是BabyMilestone对象的数组。 Child类和BabyMilestone类都负责编码/解码。 Child类中的对象正在被正确编码和解码。 BabyMilestone类中的对象不是。没有在BabyMilestone对象上调用编码器编码,而是在Child类上调用 问题:我是否需要做一些特殊的事情来编码一些属于其他东西的对象数组?欢迎任何调试建议!

enter image description here

顶级DataModel类,用于处理.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(从未调用encodewithcoder)

#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

儿童班

#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

1 个答案:

答案 0 :(得分:3)

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