核心数据 - 在后台保存到磁盘上的持久存储

Posted

技术标签:

【中文标题】核心数据 - 在后台保存到磁盘上的持久存储【英文标题】:Core Data - Saving to persistant store on disk in the background 【发布时间】:2010-11-04 10:30:13 【问题描述】:

我希望有人能够对此提供快速答案,这可能是一个非常明显的答案,但我无法理解它。

我有一个适用于 mac 的应用程序,我在其中使用 Core Data 来保存信息。一切正常,当我创建新数据时,它会在应用程序中正常显示,当我退出应用程序时,[managedObjectContext save:&error] 被成功调用,数据被存储到磁盘上的持久存储中。

我要做的是在任何信息发生更改时保存到核心数据。这背后的原因是为了防止应用程序崩溃时任何数据丢失,并且因为我将为用户提供存储在 dropbox/idisk 上的选项,所以最好立即保存信息,因为然后更改应该显示在他们正在访问相同数据的其他计算机。

到目前为止,我使用 NSNotificationCenter 发现了以下内容:

[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(saveDatabaseInBackground)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];

当数据发生变化时,成功调用:

- (void) saveDatabaseInBackground

    NSError *error = nil;
    if ([managedObjectContext hasChanges])
    
        [managedObjectContext save:&error];
    

但是,在托管对象上下文中调用 save 方法似乎会导致发布相同的通知,从而导致无限循环并导致崩溃。

有人对如何解决有任何想法吗?

谢谢,

罗伯

【问题讨论】:

【参考方案1】:

没有使用该通知来保存您的托管对象的解决方案。 NSManagedObjectContextObjectsDidChangeNotification 在 processPendingChanges 期间发布,在处理更改之后,但在调用 save 之前是安全的。如果您尝试,您将生成一个无限循环——正如您所发现的那样。这在通知的文档中有所提及。

您的要求是自动保存数据,以便在崩溃期间不会丢失任何内容。我为我的应用程序经历了类似的过程——它在应用程序商店中的生产力排名前 50 名,还包括 Dropbox 同步——并确定在大多数用例中我研究了几乎立即保存更改的数据通常足够好。与其尝试立即保存对象上的任何更改,不如每隔 n 秒检查一次更改并在必要时保存?设置一个计时器并检查您的对象是否有 isUpdated。这相当简单,但是您需要注意一些问题,例如如果保存已经在进行中,则不要尝试保存。这在同步到诸如 Dropbox 之类的服务时尤其重要,因为它可能需要很长时间才能同步。

如果您需要有关设置计时器、检查托管对象和保存的更详细代码,我将很乐意这样做。

【讨论】:

这是一个公平的观点,感谢您的回复。我已经考虑过这个选项,我想这对我来说是一个“后备”。如果这是不可能的或不切实际的,那么公平,我只是认为考虑到对某些人的要求是多么明显,这可能是可能的!我对计时器等应该没问题,我在商店里也有几个应用程序,所以我对 Objective-c 的理解很合理,只是一个核心数据新手! 相信我,我认为这对于几乎所有 Core Data 使用来说都是一个明显的要求,并且花了相当多的时间来寻找我确信存在的答案。好像不费吹灰之力。可悲的是没有。我考虑的替代实现是重要属性上的 KVO,但在考虑了权衡之后——特别是生成的代码有多脆弱和对象特定——我决定反对它。

以上是关于核心数据 - 在后台保存到磁盘上的持久存储的主要内容,如果未能解决你的问题,请参考以下文章

最佳核心数据保存策略(何时将数据保存到磁盘)

核心数据 - NSDate 属性在持久存储中发生变化

Redis持久化方案

Redis持久化方案

如何将数据持久保存到磁盘,并随机更新它,并将其有效地流式传输回 RAM?

RestKit 内存核心数据存储的配置