从 NSKeyedArchiver 加载单例状态
我有一个类,我已经将其制作成单例,并且能够使用 NSKeyedArchiver 保存它的状态,但是我无法集中精力将其状态拉出来。
在我执行此代码加载的函数中
Venue *venue = [Venue sharedVenue];
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
venue = [unarchiver decodeObjectForKey:@"Venue"];
[unarchiver finishDecoding];
,decodeObjectForKey 返回什么? 它实际上不可能是 Venue 的另一个实例,并且不会加载任何已保存的值。 在我将其转换为单例之前,保存和加载工作正常。
I have a class that I've made into a singleton and am able to save it's state using an NSKeyedArchiver, but I can't wrap my head around pulling it's state back out.
In the function that does the loading I have
Venue *venue = [Venue sharedVenue];
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
venue = [unarchiver decodeObjectForKey:@"Venue"];
[unarchiver finishDecoding];
With this code, what does decodeObjectForKey return? It can't really be another instance of Venue and it's not loading in any of the saved values. Before I converted it to a singleton saving and loading was working fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这是错误的地方。 您熟悉 NSCoding,并且通常通过使用encodeWithCoder: 和 initWithCoder: 覆盖使您的对象可编码来采用它。 使这一切变得更简单的是,您仍然可以使用 NSCoding 和 NSCoders 而无需覆盖这些方法。 您可以对共享对象的状态进行编码,而无需对共享对象本身进行编码。 这可以防止解码共享对象的尴尬问题。
这是我认为您可以做的一个示例:
这里我们有一个共享对象,它使用带密钥的存档来持久化配置,但我们不对共享对象本身进行编码。 这避免了解码单例类的第二个实例的尴尬问题。
Here's where I think this is going wrong. You're familiar with NSCoding and typically adopting it by making your object codable via encodeWithCoder: and initWithCoder: overrides. What will make this all simpler is that you can still use NSCoding, and NSCoders without overriding those methods. You can encode the state of the shared object without encoding the shared obejct itself. This prevents the awkward question of decoding the shared object.
Here's an example of what I think you could do:
Here we have a shared object, and it uses keyed archive to persist configuration, but we don't encode the shared object itself. This avoid that awkward question of decoding a second instance of the singleton class.
您需要在单例本身中进行加载,这里发生的是您创建单例,为单例分配一个 lval,然后创建一个新对象并将 lval 重新分配给该新对象,而不修改单例。 换句话说:
您想要做的是在共享场所中处理这个问题。 人们有几种方法来实现单例,所以我不能确定你在做什么,但让我们假设sharedVenue当前看起来像这样:
假设你想改变它以将对象加载到全局支持中单例:
显然,您需要以某种方式传达归档目标文件的实际路径。
根据评论进行编辑:
好的,如果您使用基于分配的单例,则需要在类 init 方法中处理此问题:
You need to do the loading in the singleton itself what is going on here is you create the single, you assign an lval to the singleton, you then create a new object and reassign the lval to that new object WITHOUT modifying the singleton. In other words:
What you want to do is deal with this in the sharedVenue. There are a couple of ways people do singletons, so I can't be sure what you are doing, but lets assume sharedVenue currently looks something like this:
Assuming that is the case you want to change it to load the object into the global backing the singleton:
Obviously you need to somehow convey the actual path to archived object file.
EDIT BASED ON COMMENT:
Okay, if you are using the alloc based singleton you need to deal with this in the classes init method: