如何有效地重置核心数据实体中的属性

时间:2011-10-31 05:28:01

标签: iphone core-data ios4

我的应用使用核心数据,并且有一个名为'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文件并发出警告,要求用户自己重启应用程序。这样做肯定比我现在快得多。是否有更快的方式来刷新实体?我可以拥有一个“备份”实体并将其复制过来吗?谢谢你的帮助。

2 个答案:

答案 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];

希望这会有所帮助:)