NSPredicate 使用 Fetch 请求不返回任何结果,可与数组过滤一起使用

发布于 10-25 00:36 字数 2652 浏览 3 评论 0原文

我的情况很简单:我的核心数据存储中有一些记录。它们的属性之一是名为“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不再见2024-11-01 00:36:08

如果 localId 是数值,则应在谓词构成中使用 NSNumber 对象,而不是 NSString

[request setPredicate:[NSPredicate predicateWithFormat:@"localId == %@", 
    [NSNumber numberWithString:localId]]];

NSPredicate 格式字符串自动引用 NSString 对象。

If localId is a numerical value, then you should use an NSNumber object in the predicate formation instead of an NSString.

[request setPredicate:[NSPredicate predicateWithFormat:@"localId == %@", 
    [NSNumber numberWithString:localId]]];

NSPredicate format strings automatically quote NSString objects.

我一直都在从未离去2024-11-01 00:36:08

不想这么说,但此类问题的最常见原因是简单的拼写错误。确保您的属性名称和谓词相同。确保您的属性名称和属性名称相同。如果对属性的引用有效,但对属性名称的引用无效,则可能存在不匹配。

您可以通过比较以下内容的返回来测试后者:

[result valueForKey:@"localID"]

... 与以下内容的返回:

result.localID

Hate to say it but the most common cause of these types of problems is simple typos. Make sure that your attribute names and the predicate are the same. Make sure that your property names and the attributes names are the same. If a reference to a property works but a reference to attribute name doesn't there is probably a mismatch.

You could test for the latter by comparing the return of:

[result valueForKey:@"localID"]

... with the return of:

result.localID
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文