1

我有一些数据由2个表的记录组成:对和项目。这些表格与多对多关系相关联。我看到两种可能的方式来填补核心数据实体。让我们已经填满了所有的项目,现在我们应该填补对。在这两种情况下,“标识符”都是附加的文本属性/字段。核心数据。 NSDictionary VS NSFetchRequest?

路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]的时间。

当我看到第二个工作方式比第一种快得多。但是它有什么隐藏的缺点?例如不会将项目保存到额外的字典会浪费内存?

回答

1

你不显示如何保存 - 这可以产生相当大的效果。

选项1具有记忆效率但不具时间效率。

选项2时有效,但不是记忆效率(你试图通过仪器运行它/旧的设备上?)。

你应该想想,你运行一个混合解决方案(并保存)批次。通过试验和分析来设置批量大小。仪器有一些核心数据工具来帮助解决这个问题。您的目标是尽可能少地利用最少的内存使用量,最少的提取次数和最少的上下文保存次数。

+0

所有项目都存储在上下文中(除了此部分数据与way2,他们另外存储在数组和字典中)。在填充数据库之前创建上下文,并在所有数据成功解析时调用save:。但是如果上下文浪费了大量的内存,那么这会浪费两种情况下的内存。 – user2083364

+1

上下文不浪费内存,当您获取对象时使用内存。所以当你读取一个数组(这是选项2)时,你的内存使用率很高。 – Wain

+0

谢谢你的回答。最后一个问题是如果我将手动释放数组以防止在方式2结束时浪费内存而不是autorelease数组? – user2083364

1

当然有一个很大的缺点。

你持有的所有数据存储在存储器例如2.当然,这始终是最快的方式,但不是最好的移动设备。

CoreData是一个对象图,而不是一个存储存储。默认情况下,它不会立即使用内存来创建对象。它在你真正开始使用它时创建对象,意味着使用这些属性。在它只是持有一个小的参考 - 所谓的故障。 CoreData平衡内存与性能,并允许您控制加载到内存中的数据和时间。从获取中获取的NSArray实际上只有少量内存已准备好。当您访问该元素时,其余部分将变为真实。我们通常没有任何时候需要所有对象的情况。通常我们的Collectionviews只显示一些对象的一些信息,但从来没有。当然,您可以简单地获取所有对象并告诉他实际加载对象。那么他将会像例子二一样快。也许在某些情况下速度更快,因为NSSet在相交等方面拥有惊人的能力。

有几个很好的WWDC研讨会展示了如何处理这个问题。一般情况下,CoreData总是最好的解决方案,除非我们谈论的是仅仅在内存中花费几千字节并且不会造成任何伤害的微不足道的数据。但是你的时间数字表明你有很多数据。并非所有数据都是必需的。拆分它,创建一个实体,以保存需要显示的必要信息,并将其余部分放入其他实体中。当你需要详细信息时,你可以访问额外的实体,并在一小段延迟后获得对象。(称为延迟加载)

请在Core数据中尝试我的建议,并查看设备运行时与使用NSDictionary解决方案时使用的内存量。我想你会看到不同之处。

+0

我使用NSSet是因为一个简单的原因:所有的链接都有反向链接。如果你有两个有多对多关系的字段被引用到同一个表格(第二个表格只允许设置一个反向链接),那么做到这一点是可行的。 感谢您的建议,我会在稍后看到内存。 项目另外有两个双参数和其他参数链接到其他设施。我检查了一下,我发现大部分时间都花在创建一对和两个项目之间的链接上。我甚至试图优化这个过程,但总时间不少于3分钟。 – user2083364

+0

我目前的解决方案是方式3,但它打破了核心数据结构。这意味着类别不与项目链接并仅包含其标识符。 最后一个问题是如果我将手动释放一个数组以防止在方式2结束时浪费内存? – user2083364

相关问题