objective-c - 如何更改在 NSKeyedArchiver 中编码的对象的层次结构?

标签 objective-c

我们已经发布了一款游戏,该游戏在整个类(class)中都使用 NSCoding 来保存/加载功能。我们现在正在开发下一个版本,但在此之前,我们需要重构代码,以使其具有更好的性能,并且更容易实现 future 的功能(这往往会发生很大变化)。

问题出现在审查新设计之后。它具有与以前版本不同的 NSCoding 层次结构。

v1.0 GameSavedFile(使用 NSKeyedArchiver)-> UserData -> User(UserData 的父级)-> 一堆对象和原语

v1.1 用户(使用 NSKeyedArchiver)-> 一堆对象和原语

v1.1 具有更简单直接的结构。在 v1.0 中,UserData 是 User 的子类,而在 v1.1 中,我们将只为所有用户数据使用一个类。

这种方式更简单实用。但是,如何在不破坏任何内容的情况下将所有 v1.0 数据移植到 v1.1?我读到有一个 setClassName:forClass: 方法,但我认为它只会用新类替换旧类。

我能想到的最干净、最安全的方法是检查游戏是否仍在使用旧版本 (v1.0)。如果是,请将 NSCoding 层次结构转换为 plist/字典,然后将其分散在 v1.1 代码中。

我愿意接受任何可能的建议/解决方案,但我更喜欢 Foundation 框架中已经可用的解决方案(如果可能的话)。

谢谢。

最佳答案

当然你应该阅读Forward and Backward Compatibility for Keyed Archives ,但它并没有真正解决您的问题。 (无论如何都要读它。)

假设您还没有发布 v1.1,这是我的建议:

  • 为 v1.1 创建一个新的保存文件名。我经常在文件名中包含版本号以简化这一点。这样可以在打开之前轻松判断您要阅读的是哪个版本。我通常更喜欢这个,而不是 Apple 建议将版本存储在文件中。 (当然,如果更改文件名导致用户混淆,或者用户可以控制文件名,那么您当然应该将版本存储在文件中。)

  • 对于 v1.0 文件,创建仅保存原始数据的类,例如 V10GameSaveFile。然后使用 setClassName:forClass: 将序列化对象移动到虚拟类类。

  • 现在您的结构已在内存中,将其转换为新的对象模型,重新保存并删除旧文件。

关于objective-c - 如何更改在 NSKeyedArchiver 中编码的对象的层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8707145/

相关文章:

objective-c - iPhone SDK 开发 obj-C 与 Interface Builder

ios - 如何制作一系列句子?

ios - 是什么导致了这种内存泄漏?

objective-c - NSPanel 不可点击,但键盘事件有效

objective-c - 错误: unrecognized selector sent to class

objective-c - 用C中的另一个数组替换数组

objective-c - 在其自定义 setter 中使用 NSString 会导致无限线程

objective-c - Cocoa 应用程序通过双击或右键单击打开文件

ios - 在 iOS 9 上从 TableView 打开 safari View Controller 并在 iOS 8 或 7 上在 safari 中打开

ios - UIScrollView,无需一直向下滚动即可检测可滚动区域高度