2

我目前正在使用 CoreData 开发 iOS 应用程序。

当应用程序第一次启动时,会针对 RESTful Web 服务发出一系列 Web 请求。

Web 服务提供一系列 json 响应,其中可以包含超过 2000 条记录。

然后解析这些记录,将其转换为各种核心数据实体并存储在我们的 SQLite 持久性存储中。

一旦这个操作完成,我们通过获取实体 A中的所有行(例如)来创建一个对象图,并创建一个我们稍后使用的对象图。

出于某种原因,在遍历存储在实体 A中的所有 NSManagedObjects 时,一些 NSManagedObjects 缺少属性值。

鉴于我们在多线程环境中工作,我们确保在单独的线程上创建单独的 managedObjectContexts - 但是,在我们最近的测试运行期间,我们已经配置了环境,使得只有一个线程一次从 SQLite 持久存储中保存/检索数据。

还可能值得注意的是,在[context save:...]我们解析了所有 2000 多条在 json 响应中返回的记录之前,我们不会执行操作。

经过一些试验和错误,我注意到问题消失了,我们每次插入都执行保存。

例如,以下代码可以正常工作:

NSManagedObjectContext *context = ...
NSError *error = ...

for(id record in collectionOfRecords){
    //create entity for insertion
    [context save:&error]
}

但这会导致缺少属性值的问题:

NSManagedObjectContext *context = ...
NSError *error = ...

for(id record in collectionOfRecords){
    //create entity for insertion     
}
[context save:&error]

问题:

[NSManagedObjectContext save:...]在必须执行操作之前,是否有最大数量的 NSManagedObjects 可以位于内存中?

4

1 回答 1

3

要回答您的问题:在需要保存之前,内存中可以有多少托管对象没有设置限制。您的应用程序可以创建托管对象而无需尽可能多地保存,当内存运行不足时,您将开始收到任何 iOS 应用程序都可以获得的正常内存警告。理想情况下,您不希望发生这种情况,并且对内存警告进行上下文保存或上下文重置可能也不是一个好主意。

但是,Apple 的文档涵盖了您在详细信息中描述的场景:

核心数据编程指南:高效导入数据

这里还有更多相关内容:

核心数据编程指南:核心数据性能

在您的情况下,您应该更频繁地保存,并且在多个线程上工作 - 您说您只从一个线程访问存储,这可能是您问题的很大一部分。您似乎没有在线程 B 的上下文中从线程 A 的上下文中获得更改 - NSManagedObjectContextObjectsDidChangeNotification 是使用较旧的线程限制模型时执行此操作的主要方式。

于 2013-03-18T21:58:02.133 回答