NSPredicate 使用 Fetch 请求不返回任何结果,可与数组过滤一起使用
我的情况很简单:我的核心数据存储中有一些记录。它们的属性之一是名为“localId”的字符串。我想找到具有特定 localId 值的记录。最明显的方法是使用 NSFetchRequest 和 NSPredicate。但是,当我进行设置时,请求返回零记录。
但是,如果我使用不带谓词的获取请求,返回所有记录,然后循环查找目标 localId 值,我确实会找到我正在查找的记录。换句话说,记录在那里,但是获取请求找不到它。
我使用获取请求和谓词的其他方法都按预期工作。我不知道为什么这个失败了。
我想这样做:
- (void)deleteResultWithLocalID:(NSString *)localId {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"WCAAssessmentResult" inManagedObjectContext:context]];
[request setPredicate:[NSPredicate predicateWithFormat:@"localId == %@", localId]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSAssert(error == nil, ([NSString stringWithFormat:@"Error: %@", error]));
if ([results count]) [context deleteObject:[results objectAtIndex:0]];
else NSLog(@"could not find record with localID %@", localId);
[self saveContext];
}
但我最终不得不这样做:
- (void)deleteResultWithLocalID:(NSString *)localId {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"WCAAssessmentResult" inManagedObjectContext:context]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSAssert(error == nil, ([NSString stringWithFormat:@"Error: %@", error]));
for (WCAAssessmentResult *result in results) {
if ([result.localId isEqualToString:localId]) {
NSLog(@"result found, deleted");
[context deleteObject:result];
}
}
[self saveContext];
}
有任何关于可能出问题的线索吗?
编辑
我发现我可以使用我创建的谓词在执行获取请求后获得我期望的结果。因此,以下方法也有效:
- (WCAChecklistItem *)checklistItemWithId:(NSNumber *)itemId {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"WCAChecklistItem" inManagedObjectContext:context]];
NSArray *foundRecords = [context executeFetchRequest:request error:nil];
foundRecords = [foundRecords filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"serverId == %@", itemId]];
if ([foundRecords count]) {
return [foundRecords objectAtIndex:0];
} else {
NSLog(@"can't find checklist item with id %@", itemId);
return nil;
}
}
更新
我遇到过其他人也遇到过这个问题:
http://markmail .org/message/7zbcxlaqcgtttqo4
他也没有找到解决办法。
天啊!我很困惑。
谢谢!
My situation is simple: I have some records in my core data store. One of their attributes is a string called "localId". There's a point where I'd like to find the record with a particular localId value. The obvious way to do this is with an NSFetchRequest and an NSPredicate. However, when I set this up, the request returns zero records.
If, however, I use the fetch request without the predicate, returning all records, and just loop over them looking for the target localId value, I do find the record I'm looking for. In other words, the record is there, but the fetch request can't find it.
My other methods in which I use fetch requests and predicates are all working as expected. I don't know why this one is failing.
I want to do this:
- (void)deleteResultWithLocalID:(NSString *)localId {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"WCAAssessmentResult" inManagedObjectContext:context]];
[request setPredicate:[NSPredicate predicateWithFormat:@"localId == %@", localId]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSAssert(error == nil, ([NSString stringWithFormat:@"Error: %@", error]));
if ([results count]) [context deleteObject:[results objectAtIndex:0]];
else NSLog(@"could not find record with localID %@", localId);
[self saveContext];
}
But I end up having to do this:
- (void)deleteResultWithLocalID:(NSString *)localId {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"WCAAssessmentResult" inManagedObjectContext:context]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSAssert(error == nil, ([NSString stringWithFormat:@"Error: %@", error]));
for (WCAAssessmentResult *result in results) {
if ([result.localId isEqualToString:localId]) {
NSLog(@"result found, deleted");
[context deleteObject:result];
}
}
[self saveContext];
}
Any clues as to what could be going wrong?
edit
I've found that I can use the predicate I'm creating to get the results I expect after the fetch request has been executed. So, the following also works:
- (WCAChecklistItem *)checklistItemWithId:(NSNumber *)itemId {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"WCAChecklistItem" inManagedObjectContext:context]];
NSArray *foundRecords = [context executeFetchRequest:request error:nil];
foundRecords = [foundRecords filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"serverId == %@", itemId]];
if ([foundRecords count]) {
return [foundRecords objectAtIndex:0];
} else {
NSLog(@"can't find checklist item with id %@", itemId);
return nil;
}
}
UPDATE
I've come across someone else experiencing this very issue:
http://markmail.org/message/7zbcxlaqcgtttqo4
He hasn't found a solution either.
Blimey! I'm stumped.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如果
localId
是数值,则应在谓词构成中使用NSNumber
对象,而不是NSString
。NSPredicate
格式字符串自动引用 NSString 对象。If
localId
is a numerical value, then you should use anNSNumber
object in the predicate formation instead of anNSString
.NSPredicate
format strings automatically quote NSString objects.