【问题标题】:Will NSKeyedArchiver serialize the whole object hierarchy regardless of object type?无论对象类型如何,NSKeyedArchiver 都会序列化整个对象层次结构吗?
【发布时间】:2016-01-23 17:29:23
【问题描述】:

如果我将一个超类对象传递给-archivedDataWithRootObject:,但该对象包含该超类的子类;整个对象图会被序列化以包含子类的实例变量还是仅包含与超类相关的实例变量?

例子:

@interface Mammal : NSObject

@property (nonatomic, copy) NSString *species;

@end

@interface Person : Mammal

@property (nonatomic, copy) NSString *name;

@end

Person *person = [[Person alloc] init];
person.species = @"Human";
person.name = @"Michael";

Mammal *mammal = person;

NSData *personData = [NSKeyedArchiver archivedDataWithRootObject:mammal];

未归档的数据是否仅包含 Mammal 实例变量?

【问题讨论】:

    标签: objective-c nskeyedarchiver


    【解决方案1】:

    首先,编译后保存对象指针的变量的静态类型根本无关紧要。也就是说,mammal 变量被声明为指向Mammal 的指针这一事实仅在编译时用于检查内容。该事实在编译后的程序中不存在,并且不会影响运行时的行为。

    其次,NSKeyedArchiver 及其 +archivedDataWithRootObject: 方法都不知道如何归档传入的对象。它们依赖于知道如何归档自身的对象。对象的类型必须符合NSCoding 协议。它的类必须实现-encodeWithCoder: 方法。对象如何编码/存档的细节完全取决于该方法的实现。

    因此,MammalPerson 都必须重写该方法以对各自类的特定数据进行编码,以便正确存档。

    一旦他们这样做了,方法调用的正常动态分派将导致在传递给+archivedDataWithRootObject:的对象上调用正确的方法。同样,这取决于对象的动态类型,而不是包含指向它的指针的变量的静态类型。

    【讨论】:

    • 是否有默认的-encodeWithCoder: 实现?如果你不为一个对象定义它,它会不会只是抛出一个异常?
    • 不,没有默认实现。如果您没有为类定义它并且该类没有继承实现,那么尝试对该类的实例进行编码将引发异常,是的。然而,从超类继承一个实现却忘记了重写它来为子类添加正确的编码行为太容易了。因此,如果您为Mammal 实现它,但忘记在Person 中覆盖和扩展它,那么归档Person 的实例将只记录与哺乳动物相关的数据,而不会记录与人相关的数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2016-05-27
    • 2022-06-28
    • 1970-01-01
    相关资源
    最近更新 更多