我在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);
}];
答案 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];