在格式字符串之外使用NSPredicate的SELF

时间:2011-06-08 20:25:26

标签: ios core-data nspredicate nsfetchedresultscontroller

我在CoreData存储上使用了fetchedResultsController,我想创建一个谓词,它会根据这个概念给我fetchedObjects:

[NSPredicate predicateWithFormat:@"%i > 0", [self countForObject:SELF]]

countForObject是一个方法,它根据参数anObject返回一个整数,我想成为SELF。

修改

看来我应该为此使用块。我已经将一些代码粘合在一起,但是当我使用它时,我的应用程序崩溃但没有反馈:

    [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings){
        return ([self countForObject:object] > 0);
    }];

1 个答案:

答案 0 :(得分:4)

您的问题在于您使用self并使用非特定测试。

您似乎希望它引用谓词正在测试的托管对象,但它实际上会引用代码出现的运行时对象(可能是一个tableview控制器)。由于“范围拖动”,使用块无法解决问题“在哪个块在相同的范围内运行它们被调用。

所以,你的代码实际上是这样的:

[NSPredicate predicateWithFormat:@"%i > 0", [myTableViewController countForObject:aPresumedConstant]];

...和块代码有同样的问题。

您的测试是非特定的,因为您没有针对托管对象的属性进行测试。相反,您为fetch实体的所有托管对象创建一个true或false的测试。

即使您的self引用返回了可用值,它也只返回一个值。假设您的countForObject:在单独的运行中返回-1,0,1。在运行时,您的谓词将解决类似这样的事情:

[NSPredicate predicateWithFormat:@"false", -1]; // -1<0 so %i>0 always resolves to false
[NSPredicate predicateWithFormat:@"false", 0]; // 0==0 so %i>0 always resolves to false
[NSPredicate predicateWithFormat:@"true", -1]; // 1>0 so %i>0 always resolves to true

在前两种情况下,fetch将返回零对象,而last将返回获取实体的所有对象。

您可能已经在谓词中看到self使用了这样的内容:

[NSPredicate predicateWithFormat:@"SELF == %@", anObject];

这里的区别在于SELF出现在引号内,因此成为谓词发送给被测对象的消息的一部分。谓词基本上说,“你SELF键是否等于anObject的SELF键?”由于每个对象都能理解自己的SELF值,因此每个对象都可以返回单独的true或false作为响应。

如果希望每个托管对象都响应countForObject上的测试,则需要为托管对象创建实体/类的countForObject和属性/属性。通常,您将创建一个瞬态属性,该属性将在每次查询时计算一个值,但不会将其持久存储到存储中。

您可以使用以下内容:

[NSPredicate predicateWithFormat:@"SELF == %@", anObject];