超级initWIthCoder返回父类型?

时间:2014-07-07 10:30:23

标签: ios objective-c nscoding initwithcoder

我想我错过了一些基本的东西......

我实现了一个包含NSCoding的类和一个包含NSCoding的子类,但是当我调用子类的initWithCoder时,出现InvalidArgument错误。

@interface Parent: NSObject<NSCoding>;


@implementation Parent

-(id)initWithCoder:(NSCoder *)decoder {
  self = [[Parent alloc] init];

  return self;
}
@end

@interface Child: Parent<NSCoding>;


@implementation Child

-(id)initWithCoder:(NSCoder *)decoder {
  self = [super initWithCoder:decoder]; //self is Parent type here
  // self = [[Child alloc] init]; if i do that, no error but no init for the parent'attribute
  if(self){
    self.childAttribute = [decoder decodeObjectForKey:@"KeyAttribute"]; // invalide argument ==> setChildAttribute doesn't exist. 
  }
  return self;
}

我一定忘记了一些基本的东西,但我无法找出... 有人有想法吗?

感谢。

2 个答案:

答案 0 :(得分:1)

您正在以错误的方式初始化Parent。调用-initWithCoder:时,已经分配了类。请记住语法:

id myObj = [[MyClass alloc] initWithArgument:...];

因此假设您在初始化程序中未分配,则设置默认值。

您可以参考ObjectiveC文档来了解如何完成此操作。 我强烈建议您查看:Concepts in ObjC Programming – Object Initialization 此外Memory Management Guide也非常有用。 ObjectiveC依赖于您应该注意的几个约定,以避免可能难以跟踪的泄漏。

初始化父母的正确方法是:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init]; // it's just a subclass of NSObject
    if (self) {
        // DECODE VARIABLES...
    }
    return self;
}

如果Parent是另一个NSCoding兼容类的子类,[super init]应该已被[super initWithCoder:aDecoder]取代;但在初始值设定项中,您无法将self设置为超类-init...方法未返回的内容。

您收到错误,因为当您调用[Child alloc]时,会分配Child的实例,但在初始化Parent期间,您将返回手动分配的Parent实例因此,您丢失了对Child的原始引用,并且该类不再匹配。

答案 1 :(得分:0)

您的Parent类初始化函数返回的对象可能是原因。您需要使用initWithCoder:函数继续初始化其父级。现在它应该只返回一个没有childAttribute属性的简单NSObject对象。

如果其他所有方法都正确连接,它应该只需要:

@implementation Parent

-(id)initWithCoder:(NSCoder *)decoder {
    self = [super initWithCoder:decoder];
    return self;
}
@end