Core Data,我如何有效地查找和删除托管对象

Posted

技术标签:

【中文标题】Core Data,我如何有效地查找和删除托管对象【英文标题】:Core Data, how can i find and delete managed objects effectively 【发布时间】:2014-01-10 17:14:34 【问题描述】:

我的应用程序向服务器发送一个获取请求,其中包含一个日期(上次更新日期)以更新其内容(核心数据中的 2 个实体,没有关系,所有属性都是字符串)...大多数时候它只接收新内容,但有时它也会收到需要更新而不是插入的旧内容。 1 表非常简单,我只获取要在数组中更新的项目的 ID(来自服务器的 ID,而不是核心数据),然后获取这些项目,然后删除它们。之后,我插入更新的项目,因为它们是新的。这就是我删除它们的方式:

-(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 个值的数组的数组,表示复合键?和谓词?我只是想知道是否有可能有效地做到这一点,如果不能,我总是可以获取所有项目并逐个检查,但为此我需要在另一个 for 中添加一个 for,这太难看了。任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

当您设计数据库时,您应该创建一个唯一的关键字段,即使它只是两个值的组合。那会让这个问题消失。

但是,现在要解决这个问题,您需要像上面那样在一个键上进行提取,然后循环第二个键。但是,您不需要在循环中执行循环。您可以对返回的数组使用第二个NSPredicate 来获取要修改的对象。

不那么难看,而且效率很高,因为您只需要磁盘一次,第二个过滤器在内存中发生。

更新

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

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

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

如果您同时测试这两个选项,谓词将运行得更快。

【讨论】:

不确定我是否遵循您的第二个选项@marcus 的逻辑,无法避免通过同时指定两个键来识别每个项目。基于一个属性获取对象数组并仅基于第二个属性对其进行过滤可能会返回您不想删除的项目。 Set of (A1, A2, B1, B2) 删除 A1,B2 全选 1(A,B) 返回 (A1, A2, B1, B2),现在全选 2(1,2) 返回 (A1, A2, B1 , B2)【参考方案2】:

我所做的是创建另一个名为“identifier”的属性,它是一个stringWithFormat:@"%@%@",key1,key2,coredata 中的额外字符串并不重要,因为它假设该实体中只有几个托管对象

【讨论】:

以上是关于Core Data,我如何有效地查找和删除托管对象的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 NSPredicate 过滤 Core Data 托管对象?

既然 objectID 在临时对象和永久对象之间发生变化,如何有效地处理 Core Data 中的临时对象?

如何在代码中复制 Core Data 托管对象

如何在通过 Core Data 保存我的 RestKit 托管对象之前对其进行修改?

从 Core Data 中删除对象和切换视图控制器时崩溃

Core Data 托管对象上下文线程同步