【问题标题】:Programmatically loading an object model created using NSCoding以编程方式加载使用 NSCoding 创建的对象模型
【发布时间】:2010-11-05 01:16:30
【问题描述】:

1.0 版应用程序有一个数据模型,它使用 NSKeyed(Un)Archiver 类保存/加载,因为所有模型类都遵循 NSCoding 协议。假设存在以下层次结构:

-> Houses (NSMutableArray)
-> -> House (Custom Object)
-> -> -> Color (3 ints, RGB)
-> -> -> Number of Residents (int)

假设有以这种方式存储的旧文件,但需要使用以下较新的数据模型将其加载到应用程序的 2.0 版本中以实现向后兼容性:

-> Neighborhood (Maintains NSMutableArray, among other properties)
-> -> TownHouse
-> -> -> Color (3 ints, RGB)
-> -> -> Occupants (NSMutableArray)
-> -> (Other types of houses)

显然,有些数据会丢失,需要填写。例如。需要为之前存在的每个“居民数量”创建一个基本的“居住者”对象。我正在寻找的是一种以编程方式加载先前数据模型的方法,特别是如果我只有一个类/层次结构列表,而不是 .m/.h 文件本身。

所以我想做的是(假设我有一个文件 Houses.data,它是使用 Houses 数组序列化的):

NSFile *legacyFile;
Neighborhood *hood = [Neighborhood neighborhoodFromLegacyFile:legacyFile];

有什么想法吗?

【问题讨论】:

    标签: ios objective-c iphone xcode nscoding


    【解决方案1】:

    我认为这里的技巧是使用 NSKeyedUnarchiver 提供的 setClass:forClassName: 函数。它允许您说:“使用 TownHouse 类反序列化 House 类的所有实例。”

    然后您需要修改 TownHouse 的 initWithCoder: 函数来解码任一层次结构。您可以通过调用 decodeObject 或 decodeObjectForKey: 来完成此操作,然后使用 isKindOfClass: 查看您正在处理的对象类型。您还可以使用 containsValueForKey: 在尝试读出某些键之前检查它们。

    希望对你有帮助!

    【讨论】:

    • 有点用!一个问题是“Houses”数组以及其他一些对象被包装在一个 NSArray 中。这使得序列化一个对象变得容易,通过调用 [NSKeyedArchiver archivedDataWithRootObject:(NSArray *)topLevelArray];为了解决这个问题,我一直在使用 [NSKeyedUnarchiver unarchiveObjectWithData:topLevelArrayData];。那么如何使用 unarchiveObjectWithData: 方法,因为它是一个类方法,带有自定义 NSKeyedUnarchiver 的实例?
    • 嘿克雷格! NSKeyedUnarchiver 类在类和实例级别都提供了 setClass:forClassName: 函数,因此您实际上可以说 [NSKeyedUnarchiver setClass:forClassName:] 然后使用 [NSKeyedUnarchiver unarchiveObjectWithData:topLevelArrayData]。如果需要,您可以创建 NSKeyedUnarchiver 的实例,但这不是必需的。无论哪种方式,它都应该使用您之前提供的设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 2017-10-30
    • 2013-10-12
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多