don*_*ile 53 iphone core-data objective-c
我想知道对象是否在Core Data中持久存在.例如,我在Core Data中有Friends,我通过firstName识别它们.我可以查询核心数据以查看"George"是否已知.如果结果集数组包含多个零对象,我知道George就在那里.但是核心数据将整个内容加载到内存中,我实际上只是想知道乔治是否存储.
我怎样才能以最有效的方式做到这一点?
Mas*_*aro 96
设置Core Data请求,而不是实际发出查询,请执行以下操作:
NSError *error = nil;
NSUInteger count = [managedObjectContext countForFetchRequest:request
error:&error];
if (!error) {
return count;
} else {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
实际上,该方法countForFetchRequest:error:
返回给定的获取请求在传递给它时将返回的对象数executeFetchRequest:error:
.
编辑:( 由Regexident提供)
正如Josh Caswell正确评论的那样,处理错误的正确方法是:
if (count == NSNotFound) {
NSLog(@"Error: %@", error);
return 0;
}
return count;
Run Code Online (Sandbox Code Playgroud)
或者这个(没有错误记录):
return (count != NSNotFound) ? count : 0;
Run Code Online (Sandbox Code Playgroud)
sha*_*ikh 25
是的,绝对有更好的方法.像往常一样设置一个获取请求,但是,如果它已经传递给executeFetchRequest,则只需要询问它将返回的对象数:错误:
这可以使用
- (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error:(NSError **)error;
Run Code Online (Sandbox Code Playgroud)
像这样的东西:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
如果目标是检查对象是否存在,解决方案是在您的朋友模型中实现此方法:
-(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;
}
}
Run Code Online (Sandbox Code Playgroud)
根据Core Data Documentation,您不应该继续查看对象是否存在.
在许多情况下,您可能需要查找一组离散输入值的现有对象(已存储在商店中的对象).一个简单的解决方案是创建一个循环,然后为每个值依次执行一个fetch以确定是否存在匹配的持久化对象,依此类推.这种模式不能很好地扩展.如果使用此模式分析应用程序,通常会发现fetch是循环中较昂贵的操作之一(与仅迭代项目集合相比).更糟糕的是,这种模式将O(n)问题转化为O(n ^ 2)问题.
编辑3月16日:
我不是数据库专家,但由于人们要求更高效的解决方案,请考虑以下设置:
set1 = [apple, orange, banana, pineapple, lettuce]
Run Code Online (Sandbox Code Playgroud)
我们想知道[mango, apple, grape]
是否属于这一组.
文档告诉我们不要遍历[芒果,苹果,葡萄]并查询数据库依次查找每个项目,因为这很慢.
考虑这个解决方案
在服务器端散列集:
hash([mango, apple, grape]) = 234095dda321affe...
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过询问服务器是否有任何更改来完全绕过Core Data.如果集合不同,则可以将对象转储到托管对象上下文中并进行批量保存.
如果您真的想要查看每个对象是否是该集合的一部分,您可以根据索引特征进行提取,例如"带有皮肤的水果".
SWIFT 5 更新:
func checkIfItemExist(id: Int, type: String) -> Bool {
let managedContext = CoreDataStack.sharedInstance.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "DetailsEntity")
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: "id == %d" ,id)
fetchRequest.predicate = NSPredicate(format: "type == %@" ,type)
do {
let count = try managedContext.count(for: fetchRequest)
if count > 0 {
return true
}else {
return false
}
}catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
return false
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32023 次 |
最近记录: |