我的应用使用核心数据,并且有一个名为'beenSeen'的属性。当用户刷新应用程序时,所有'beenSeen'值都将更改为0.在具有超过2000个对象的iPod Touch第二代上,刷新需要一分钟。我的代码如下所示:
for (Deck *deck in self.deckArray) {
if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
[deck setBeenSeen:[NSNumber numberWithInt:0]];
[self.managedObjectContext save:&error];
}
}
我也在考虑删除sqlite文件并发出警告,要求用户自己重启应用程序。这样做肯定比我现在快得多。是否有更快的方式来刷新实体?我可以拥有一个“备份”实体并将其复制过来吗?谢谢你的帮助。
答案 0 :(得分:1)
嗯。我建议的第一个优化是
for (Deck *deck in self.deckArray) {
if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
[deck setBeenSeen:[NSNumber numberWithInt:0]];
}
}
[self.managedObjectContext save:&error];
我怀疑它可能会加速做一个大的上下文保存,而不是2000个小的。
第二个建议是尝试摆脱if
测试 - 如果大多数beenSeen
值从1变为0,其他值已经为0,那么你可能会好吧,只需将它们全部设置为0,并节省单独检查每个的时间。 (另一方面,如果有10,000个对象并且您正在重置其中的2,000个,那么摆脱测试可能不是最佳的。)
for (Deck *deck in self.deckArray) {
[deck setBeenSeen:[NSNumber numberWithInt:0]];
}
[self.managedObjectContext save:&error];
}
第三个建议是考虑以另一种方式实现 - 例如,你的套牌对象可以实现lastSeen
属性,存储上次看到套牌时的日期和时间,然后代替做大规模重置(并写入2,000个核心数据行),您可以根据上次用户刷新的时间戳测试每个套牌的lastSeen
日期和时间。
答案 1 :(得分:1)
试试这个,首先,使用谓词过滤数组:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"beenSeen == %@",
[NSNumber numberWithInt:1]];
NSArray* filtered = [self.deckArray filteredArrayUsingPredicate:predicate];
现在设置新值:
[filtered setValue:[NSNumber numberWithInt:0] forKeyPath:@"beenSeen"];
最后保存上下文:
[self.managedObjectContext save:&error];
希望这会有所帮助:)