0

私は何か基本的なものが欠けていると思います...

NSCodingでクラスと子を実装しましたが、子クラスのNSCodingを呼び出すとエラーが発生します。initWithCoderInvalidArgument

@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 のドキュメントを参照してください。これを確認することを強くお勧めします: Concepts in ObjC Programming – Object Initialization
また、メモリ管理ガイドも非常に役立ちます。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たインスタンスが返されるため、エラーが発生します。したがって、元の参照が失われ、クラスが一致しなくなります。ParentChild

于 2014-07-07T11:17:05.077 に答える
0

親クラスの初期化関数から返されたオブジェクトが原因である可能性があります。initWithCoder: 関数を使用して、その親を初期化し続ける必要があります。これで、childAttribute プロパティのない単純な NSObject オブジェクトが返されるはずです。

他のすべてが適切に接続されている場合は、次のようにする必要があります。

@implementation Parent

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