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

发布于 2024-12-13 03:22:24 字数 519 浏览 1 评论 0原文

我的应用程序使用核心数据并具有一个名为“beenSeen”的属性。当用户刷新应用程序时,所有“beenSeen”值 1 都会更改为 0。在包含超过 2000 个对象的 iPod Touch 2nd gen 上,刷新需要一分钟多的时间。我的代码如下所示:

    for (Deck *deck in self.deckArray) {
        if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
            [deck setBeenSeen:[NSNumber numberWithInt:0]];
            [self.managedObjectContext save:&error];           
        }
    }

我还在考虑删除 sqlite 文件并发出警报,要求用户自行重新启动应用程序。这样做肯定比我现在快得多。有没有更快的方法来刷新实体?我可以有一个“备份”实体并将其复制吗?感谢您的任何帮助。

My app uses Core Data and has an attribute called 'beenSeen'. When a user refreshes the app, all 'beenSeen' values of 1 are changed to 0. On an iPod Touch 2nd gen with over 2000 objects, refreshing takes over a minute. My code looks like this:

    for (Deck *deck in self.deckArray) {
        if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
            [deck setBeenSeen:[NSNumber numberWithInt:0]];
            [self.managedObjectContext save:&error];           
        }
    }

I'm also considering deleting the sqlite file and having an alert ask the user to restart the app themselves. Doing that sure is a whole lot quicker than what I have now. Is there a quicker way to refresh an entity? Could I have a 'backup' entity and copy it over? Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酷到爆炸 2024-12-20 03:22:24

嗯。我建议的第一个优化是,

for (Deck *deck in self.deckArray) {
    if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
        [deck setBeenSeen:[NSNumber numberWithInt:0]];
    }
}
[self.managedObjectContext save:&error];           

我怀疑它可能会加快执行一次大上下文保存的速度,而不是 2,000 个小上下文保存。

第二个建议是尝试摆脱 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 个核心数据行) Deck 的 lastSeen 日期和时间与上次用户刷新的时间戳相对应。

Hm. The first optimization I'd suggest would be

for (Deck *deck in self.deckArray) {
    if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
        [deck setBeenSeen:[NSNumber numberWithInt:0]];
    }
}
[self.managedObjectContext save:&error];           

I suspect it might speed things up to do one big context save, instead of 2,000 little ones.

The second suggestion would be to try getting rid of the if test – if the majority of your beenSeen values are changing from 1 to 0, and the others are already 0, then you might as well just set all of them to 0 and save the time of checking each one individually. (On the other hand, if there are 10,000 objects and you're resetting 2,000 of them, then getting rid of the test might not be optimal.)

for (Deck *deck in self.deckArray) {
    [deck setBeenSeen:[NSNumber numberWithInt:0]];
    }
    [self.managedObjectContext save:&error];           
}

The third suggestion would be to think about implementing this another way – for instance, your deck object could implement a lastSeen attribute, storing the date and time when the deck was last seen, and then instead of doing a mass reset (and writing 2,000 Core Data rows) you could just test each deck's lastSeen date and time against the timestamp of the last user refresh.

对你再特殊 2024-12-20 03:22:24

试试这个,首先,使用谓词过滤数组:

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

希望这有帮助:)

Try this, First, filter the array using a predicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"beenSeen == %@", 
                          [NSNumber numberWithInt:1]];

NSArray* filtered = [self.deckArray filteredArrayUsingPredicate:predicate];

Now set the new value:

[filtered setValue:[NSNumber numberWithInt:0] forKeyPath:@"beenSeen"];

Finally save the context:

[self.managedObjectContext save:&error];

Hope this helps :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文