【问题标题】:NSPredicate Returns No Results with Fetch Request, Works with Array FilteringNSPredicate 使用 Fetch 请求不返回任何结果,适用于数组过滤
【发布时间】:2011-07-21 07:48:03
【问题描述】:

我的情况很简单:我的核心数据存储中有一些记录。它们的属性之一是一个名为“localId”的字符串。有一点我想找到具有特定 localId 值的记录。显而易见的方法是使用 NSFetchRequest 和 NSPredicate。但是,当我设置它时,请求返回零记录。

但是,如果我使用不带谓词的 fetch 请求,返回所有记录,然后循环遍历它们以查找目标 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

他也没有找到解决办法。

天哪!我被难住了。

谢谢!

【问题讨论】:

    标签: ios core-data nspredicate nsfetchrequest


    【解决方案1】:

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

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

    [result valueForKey:@"localID"]
    

    ...返回:

    result.localID
    

    【讨论】:

    • 感谢您的提示!我会检查并确保我的东西拼写正确。然而,这个问题发生在几个属性上,所以我倾向于认为这是更基本的问题。希望我错了!会回来报告。再次感谢。
    • 你知道,这不可能是问题,因为正如我在问题中所说,我可以在之后使用我尝试在 fetch 请求中使用的相同谓词过滤结果。所以谓词本身不可能是问题,至少在拼写方面不是。为什么谓词对过滤结果数组有效,但对提取请求无效?
    • 上面的代码没有显示完全相同的谓词。此外,如果您定义了 NSManagedObject 子类,则可以创建与实体属性名称不一致的属性名称。 fetch 将查找实体属性名称,而数组上的谓词将查找类属性名称。
    • 我在自己的代码和其他代码中都经常看到这种情况。失败的简单谓词几乎总是某处拼写错误的结果。
    • 我仍然不明白拼写错误如何导致这种特殊行为,其中谓词因获取请求而失败,但可以正常过滤获取请求的结果。
    【解决方案2】:

    如果localId 是一个数值,那么您应该在谓词结构中使用NSNumber 对象而不是NSString

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

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

    【讨论】:

    • 谢谢!这是一个很好的观点,但 localId 是一个字符串值。所以我认为这不是问题。我将编辑我的问题以明确说明。
    • 现在看来这个问题对于我所有的谓词获取请求来说都是常见的,无论是字符串还是数值!啊!
    猜你喜欢
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多