1

我有一些数据包含 2 个表的记录:对和项目。这些表通过多对多关系链接。我看到了 2 种可能的方法来填充核心数据实体。让我们已经填写了所有项目,现在我们应该填写对。在这两种情况下,“标识符”都是附加的文本属性/字段。

方式 1(仅限 NSFetchRequest):

//get data which should be converted to core data entities
id pairsInfoArray = ...; 
for (id pairInfo in pairsInfoArray) {

    //get items by identifier using NSFetchRequest
    id item1 = ...;
    id item2 = ...;
    //create pair entity
    id pair = ...;
    pair.items = [NSSet setWithObjects:item1, item2, nil];
}

方式 2(仅调用一次 NSFetchRequest 并使用 NSDictionary/NSMutableDictionary 代替):

//get all items via NSFetchRequest
NSArray *itemsObjArray = ...;
//place all the items into array as key = item.identifier, value = item (as object)
NSMutableDictionary *itemsObjDict = ...;
//get data which should be converted to core data entities
id pairsInfoArray = ...;
for (id pairInfo in pairsInfoArray) {

    //get items by key from itemsObjDict
    id item1 = ...;
    id item2 = ...;
    //create pair entity
    id pair = ...;
    pair.items = [NSSet setWithObjects:item1, item2, nil];
}

我的所有数据(不仅是项目和对)在 5 分钟(方式 1)和 45 秒(方式 2)内填充。它包括执行时间[context save:nil]

正如我所见,第二种方式比第一种方式工作得快得多。但它有什么隐藏的缺点吗​​?例如,将项目保存到附加字典不会浪费内存吗?

4

2 回答 2

1

当然有一个很大的缺点。

在示例 2 中,您将所有数据保存在内存中。当然,这始终是最快的方式,但对于移动设备来说并不是最好的方式。

CoreData 是一个对象图而不是持久存储。默认情况下,它不会立即使用内存来创建对象。当您实际开始使用它时,它会创建对象,这意味着使用属性。在它只包含一个小参考之前 - 所谓的故障。CoreData 平衡内存与性能,并允许您控制将哪些数据加载到内存中以及何时加载。您从 fetch 中获得的 NSArray 实际上在内存中只准备了几个对象。当您访问该元素时,其余部分将变为现实。当我们一直需要所有对象时,我们通常不会遇到任何情况。通常我们的 Collectionviews 只显示一些对象的一些信息,而不是全部。当然,您可以简单地获取所有对象并告诉他实际加载对象。然后他将和示例二一样快。

有一些很好的 WWDC 研讨会展示了如何处理这个问题。一般来说,CoreData 始终是最好的解决方案,除非我们谈论仅在内存中花费几 kb 并且持有它们不会造成任何伤害的琐碎数据。但是你的时间数字告诉你有很多数据。并非始终需要此数据中的所有内容。拆分它,创建一个包含您需要显示的必要信息的实体,并将其余信息放在一个额外的实体中。当您需要详细信息时,您可以访问额外的实体,并稍加延迟即可获得该对象。(称为延迟加载)

试试我在核心数据中的建议,看看你在设备上运行时用了多少内存,而不是你的 NSDictionary 解决方案。我想你会看到不同之处。

于 2013-10-05T10:15:59.500 回答
1

你没有展示你是如何保存的——这可能会产生很大的影响。

选项 1 节省内存但不节省时间。

选项 2 节省时间但不节省内存(您是否尝试过通过 Instruments / 在旧设备上运行它?)。

您应该考虑运行(和保存)批处理的混合解决方案。通过试验和分析设置批量大小。Instruments 有许多 Core Data 工具可以帮助解决这个问题。您的目标是以最少的内存使用量、最少的提取次数和最少的上下文保存次数来尽可能缩短时间。

于 2013-10-05T10:00:27.853 回答