核心数据,如何有效地查找和删除托管对象 [英] Core Data, how can i find and delete managed objects effectively

查看:153
本文介绍了核心数据,如何有效地查找和删除托管对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程式会传送取得要求给一个日期(上次更新日期)的服务器来更新其内容(核心数据中有2个实体,没有关系,所有属性都是字符串)...大多数时间只接收新内容,但有时它还接收需要更新而不是刚刚插入的旧内容。 1表是非常简单的我只是得到的ids(id从服务器不形成核心数据)的项目,将要在数组中更新,我做这些项目的提取,然后删除它们。之后,我插入更新的项目,因为他们是新的。这是我如何删除他们:

My app sends a get request to a server with a date (date of last update) to update its content (2 entities in core data, no relationships, all attributes are strings)... most of the time it only receives new content but sometimes it also receives the old content that needs to be updated instead of just inserted. 1 table is pretty straight forward I just get the ids (id from server not form core data) of the items that are going to be updated in an array and I make a fetch of those items and then delete them. After that I insert the updated items as they were new. This is how I delete them:

-(void)deleteOfEntity:(NSString*)entityName theItemsWithIds:(NSArray*)ids{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext: [self managedObjectContext]];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesPropertyValues:NO];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(id IN %@)", ids]];
NSError *error;
NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
if(fetchedObjects && [fetchedObjects count]>0){
    for (NSManagedObject* toDelete in fetchedObjects) {
        [[self managedObjectContext] deleteObject:toDelete];
    }
}

}

,因为标识每个项目的属性名称通常是ID。但是其他表需要2个属性来标识项目,如复合键。如何构建ids数组?一个包含2个值的数组的数组,表示复合键?和谓词?我只想知道是否可以有效地做到这一点,如果不是我总是可以获取所有的项目,并检查1由1,但因为我需要一个在另一个 for 这是丑陋的。

because the attribute name which identifies each item is the ID as usually. But the other table needs 2 attributes to identify items, like a composite key. How do I build up the array of "ids"? an array with arrays of 2 values indicating the composite key? and the predicate? I just want to know if it is possible to do this efficiently, if not I can always fetch all the items and check 1 by 1 but for that I need a for inside another for and that is to ugly. Any help is appreciated.

推荐答案

设计数据库时,应该创建一个唯一的键字段,即使它只是一个复合的两个值。这将使这个问题消失。

When you designed the database you should have created a unique key field, even if it is just a composite of the two values. That would have made this question go away.

然而,为了解决这个问题,现在你需要做一个类似于你上面的一个键,然后循环第二个键。但是,您不需要在循环中执行循环。您可以对返回的数组使用第二个 NSPredicate 来获取要修改的对象。

However, to solve the problem now you need to do a fetch on one key similar to what you have above and then loop over the second key. However, you do not need to do a loop within a loop. You can use a second NSPredicate against that returned array to get the objects to modify.

较不丑陋,效率更高,因为您只能使用磁盘一次,而第二个过滤器正在内存中。

Less ugly and quite efficient since you are only going to disk once and the second filter is happening in memory.

@DuncanGroenwald是正确的,你仍然必须循环遍历每个对象,但有循环,并有循环。

@DuncanGroenwald is correct that you still must loop through every object, but there is looping and there is looping.

一个开发人员编写for循环,然后在该for循环中执行字符串比较效率明显低于让框架执行相同的选项。怎么样?对数组使用 NSPredicate

A developer writing a for loop and then doing a string compare inside of that for loop is significantly less efficient then letting the frameworks perform the same option. How? With a NSPredicate against the array:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"someValue IN %@", idArray];
NSArray *results = [origArray filteredArrayWithPredicate:predicate];

如果测试这两个选项,则谓词运行速度明显更快。

If you test both options, the predicate will run significantly faster.

这篇关于核心数据,如何有效地查找和删除托管对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆