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

Sti*_*and 2 core-data nspredicate nsfetchedresultscontroller ios

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

[NSPredicate predicateWithFormat:@"%i > 0", [self countForObject:SELF]]
Run Code Online (Sandbox Code Playgroud)

countForObject 是一种基于参数 anObject 返回整数的方法,我希望将其作为 SELF。

编辑

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

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

Tec*_*Zen 5

您的问题在于您使用self和使用非特异性测试。

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

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

[NSPredicate predicateWithFormat:@"%i > 0", [myTableViewController countForObject:aPresumedConstant]];
Run Code Online (Sandbox Code Playgroud)

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

您的测试是非特定的,因为您没有针对托管对象的属性进行测试。相反,您创建一个测试,该测试对于提取实体的所有托管对象是真还是假。

即使您的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
Run Code Online (Sandbox Code Playgroud)

在前两种情况下,提取将返回零个对象,而最后一个将返回提取实体的所有对象。

您可能已经self在谓词中看到过这样的用法:

[NSPredicate predicateWithFormat:@"SELF == %@", anObject];
Run Code Online (Sandbox Code Playgroud)

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

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

你会像这样使用它:

[NSPredicate predicateWithFormat:@"SELF == %@", anObject];
Run Code Online (Sandbox Code Playgroud)