我想我错过了一些基本的东西…
我实现了一个具有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;
}
我一定是忘记了一些基本的东西,但是我找不出是什么……有人知道吗?
谢谢。
您初始化Parent
的方式错误。当-initWithCoder:
被调用时,类已经被分配了。记住语法:
id myObj = [[MyClass alloc] initWithArgument:...];
所以假设在初始化器中你不分配,你设置默认值。
你可以参考objective - c文档,看看这应该如何完成。我强烈推荐你看看这个:ObjC编程中的概念-对象初始化。
此外,内存管理指南也非常有帮助。objective - c依赖于几个你应该知道的约定,以避免可能变得难以跟踪的泄漏。
初始化父节点的正确方法是:
- (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
和类不再匹配。
从父类初始化函数返回的对象可能是原因。你需要用initWithCoder:函数不断初始化它的父类。现在它应该只是返回一个简单的NSObject对象,没有childdattribute属性。
如果其他的都连接好了,它应该只需要:
@implementation Parent
-(id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
return self;
}
@end