带有 Predicate 的 NSFetchRequest 不返回对象

Posted

技术标签:

【中文标题】带有 Predicate 的 NSFetchRequest 不返回对象【英文标题】:NSFetchRequest with Predicate not returning objects 【发布时间】:2013-09-11 22:04:56 【问题描述】:

在我的 Delegate 中,我指定了以下方法来检索 NSManagedObjects 的 NSSet:

- (NSSet *) entitiesForName : (NSString *)entityName matchingAttributes : (NSDictionary *)attributes 
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext: [NSThread isMainThread] ? managedObjectContext : bgManagedObjectContext];

NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity: entity];

NSMutableArray *subPredicates = [[NSMutableArray alloc] init];
[attributes enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) 
    if ([value class] == [NSString class]) 
        NSString *sValue = (NSString *)value;
        [subPredicates addObject:[NSPredicate predicateWithFormat:@"%@ == '%@'", key, [sValue stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]];
     else 
        [subPredicates addObject:[NSPredicate predicateWithFormat:@"%@ == %@", key, value]];
    
];
NSPredicate *matchAttributes = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
NSLog(@"matchPredicate: %@", [matchAttributes description]);
[fetch setPredicate: matchAttributes];

NSError *error;
NSSet *entities = [NSSet setWithArray: [managedObjectContext executeFetchRequest:fetch error:&error]];

if (error != nil) 
    NSLog(@"Failed to get %@ objects: %@", entityName, [error localizedDescription]);
    return nil;


return [entities count] > 0 ? entities : nil;

然后我使用我知道存在的实体并匹配我知道具有某些相同值的属性来启动此方法(我检查了 sqlite 文件):

[self entitiesForName:@"Lecture" matchingAttributes:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"attending"]]

控制台输出以下内容(显示谓词):

2013-09-11 22:47:20.098 CoreDataApp[1442:907] matchPredicate: "attending" == 0

关于 NSObject 实体的信息: - 属性“参加”是一个 BOOL(在类中翻译为 NSNumber) - 此表(Lecture 实体)中有许多记录,一半“出席”值为 0,另一半为 1 - 使用上面的方法-entitiesForName,它返回一个空集

其他信息: 我定义了另一种方法来检索相同的方式,但没有谓词(检索所有托管对象),这可以从同一个表中进行。我使用了这个,分析从中检索到的记录也证明有些“参加” 0 和有些 1

问题: 我的 -entitiesForName 方法有什么问题会导致集合返回为空吗?

【问题讨论】:

【参考方案1】:

您不应该使用 %@ 作为密钥 - 您需要使用 %K 作为密钥路径。

例如

[NSPredicate predicateWithFormat:@"%K == %@", key, value]

您可以在Predicate Programming Guide找到更多信息

在您当前的情况下,密钥被视为字符串

【讨论】:

以上是关于带有 Predicate 的 NSFetchRequest 不返回对象的主要内容,如果未能解决你的问题,请参考以下文章

为啥 LINQ 中的 LastOrDefault(predicate) 比 FirstOrDefault(predicate) 快

带有 Querydsl 的 JPA 谓词

如何使用Predicate以及如何自定定义Predicate委托

Function, Predicate, Supplier

JDK中Predicate接口源码解析和使用详解

JDK中Predicate接口源码解析和使用详解