我们已经发布了一款游戏,该游戏在整个类(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/