0

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

我实现了一个类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;
}

我一定忘记了一些基本的东西,但我不知道是什么......有人有想法吗?

谢谢。

4

2 回答 2

1

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

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

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

您可以参考 ObjectiveC 文档以了解应该如何完成此操作。我强烈建议您查看:ObjC 编程中的概念 – 对象初始化内存管理指南
也很有帮助。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并且该类不再匹配。

于 2014-07-07T11:17:05.077 回答
0

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

在所有其他正确连接的情况下,它应该只需要:

@implementation Parent

-(id)initWithCoder:(NSCoder *)decoder {
    self = [super initWithCoder:decoder];
    return self;
}
@end
于 2014-07-07T11:20:21.623 回答