1

我在 iOS 4 iPhone 应用程序中使用 CoreData(以 SQLite 作为存储)来存储我最初从 xml 文件中检索的数据。我的数据模型包含超过 15 个实体,我担心内存消耗,因为我看到 CoreData 在内存中创建所有 NSManagedObject 来表示我的数据模型的对象图。我使用基于 SAX libxml2 的解析器解析 xml 文件,并尝试将每个实体的“聚集集”逐块存储在一起,但我想在插入此聚集并保存托管上下文后释放每个托管对象,按顺序为下一个聚集节省内存。我看到我必须使用 refreshObject: mergeChanges: 来平衡每个对象在通过关系与其他对象关联时收到的多重保留(如数据模型中所设计)。我在保存上下文后这样做,但接下来当我尝试在商店中再次查找时,试图获取我插入的内容,然后它什么也没返回。我错过了什么吗?

4

3 回答 3

2

如果您所做的只是导入(例如,您不需要保留插入的对象以显示给用户等等),您可以[moc reset]在保存后简单地使用。所以算法看起来像这样:

NSManagedObjectContext* moc = ...;
while ([xmlData hasMoreObjects]) {
    // Create e.g. 500 objects and insert them into the managed object context
    NSError* error = nil;
    if (![moc save:&error]) {
        // handle the error
    }
    [moc reset]; // Here the inserted objects get released in the core data stack
}

重置托管对象上下文的作用与刷新每个对象的作用相同(就像您之前所做的那样)。此外,您应该考虑在 上使用[[NSManagedObject alloc] initWithEntity:insertIntoManagedObjectContext:]而不是便捷方法NSEntityDescription,因为您可以在不再需要它们之后释放它们,并且在自动释放池被清除之前它们不会留在内存中。

看看 Core Data Programming Guide,因为它包含一个以有效导入数据为中心的完整部分,以及一个关于使用 Core Data 进行内存管理的部分。

于 2010-07-10T09:20:56.307 回答
1

您不能直接/手动管理托管对象的内存,因为上下文控制了对象的生命周期以维护图形完整性。

如果您可以在离散块中处理导入,请在每个块之后保存上下文,然后:

[context refreshObject:theObject mergeChanges:NO]

...这会将新保存的对象转换为故障,因此它们占用的内存很少。

您只需要使用故障来设置关系,因此在前一个块中处理的对象仍可用于在当前块中设置关系。

只要有可能,我会在一个过程中创建对象,保存它们,将它们转换为错误,然后在下一个过程中设置关系。如果您有所需的关系,这并不总是可行的。

如果您还没有这样做,您可能想查看核心数据编程指南:有效导入数据。

于 2010-07-10T13:09:31.683 回答
0

我认为每次更改都必须这样做

NSManagedObjectContext *moc;
NSError *error;
[moc save:&error];

否则会被丢弃

于 2010-07-10T08:54:11.160 回答