最快的方法来检查核心数据中是否存在一个对象?

我想看看一个对象是否坚持在核心数据或不。 例如,我有核心数据中的朋友,我用firstName标识他们。 我可以查询核心数据来查看“George”是否已知。 如果结果集数组包含多于零的对象,我知道乔治在那里。 但核心数据将整个事物加载到内存中,而我只是想知道George是否存储了。

我将如何做到最有效的方式?

设置核心数据请求,而不是实际发出查询,执行以下操作:

NSError *error = nil; NSUInteger count = [managedObjectContext countForFetchRequest:request error:&error]; if (!error) { return count; } else { return 0; } 

在实践中, countForFetchRequest:error:方法返回给定的获取请求在传递给executeFetchRequest:error:会返回的对象的数量executeFetchRequest:error:


编辑:( 由Regexident)

正如Josh Caswell正确地评论的那样,正确的处理错误的方法是:

 if (count == NSNotFound) { NSLog(@"Error: %@", error); return 0; } return count; 

或者这个(没有错误logging):

 return (count != NSNotFound) ? count : 0; 

是的,肯定有更好的方法。 像平常一样设置一个提取请求,但是,如果它已经传递给executeFetchRequest,只需要询问它将返回的对象的数量:error:

这可以使用

 - (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error:(NSError **)error; 

像这样的东西:

 - (int) numberOfContacts{ NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSManagedObjectContext *managedObjectContext = yourManagedObjectContext; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Contacts" inManagedObjectContext:managedObjectContext]; [request setEntity:entity]; NSError *error = nil; NSUInteger count = [managedObjectContext countForFetchRequest:request error:&error]; [request release]; if (!error){ return count; } else return -1; } 

如果目标是检查对象是否存在,解决scheme是在您的朋友模型中实现此方法:

 -(BOOL)exist { NSManagedObjectContext *managedObjectContext = yourManagedObjectContext; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Friends" inManagedObjectContext:managedObjectContext]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entity]; [request setFetchLimit:1]; [request setPredicate:[NSPredicate predicateWithFormat:@"firstName == %@", self.firstName]]; NSError *error = nil; NSUInteger count = [managedObjectContext countForFetchRequest:request error:&error]; if (count) { return YES; } else { return NO; } } 

根据核心数据文档 ,您不应该继续查看是否存在对象。

在许多情况下,您可能需要为一组离散input值查找现有对象(已保存在商店中的对象)。 一个简单的解决scheme是创build一个循环,然后为每个值依次执行一次提取以确定是否存在匹配的持久对象等等。 这种模式不能很好地扩展。 如果使用这种模式分析应用程序,通常会发现获取是循环中更昂贵的操作之一(与仅迭代项目集合相比)。 更糟糕的是,这种模式将一个O(n)问题变成一个O(n ^ 2)问题。

编辑3月16日
我不是一个数据库专家,但是因为人们正在寻求一个更有效的解决scheme,所以请考虑一下:

 set1 = [apple, orange, banana, pineapple, lettuce] 

我们想知道[mango, apple, grape]是否属于这一套。

文档告诉我们不要遍历[芒果,苹果,葡萄],并依次查询数据库,因为这很慢。

考虑这个解决scheme:

散列在服务器端的集合:

 hash([mango, apple, grape]) = 234095dda321affe... 

然后,您可以通过询问服务器是否有任何更改来完全绕过核心数据。 如果集合不同,则可以将对象转储到托pipe对象上下文中,然后执行批量保存。

如果你真的希望看看每个对象是否属于这个集合的一部分,那么你可以根据一个索引特征(例如“带皮的水果”)进行一次抓取。