核心数据,NSPredicate,ANY key.path == nil

时间:2012-11-02 10:57:17

标签: core-data nspredicate

我想出了一个使用子查询的解决方案,但我不明白为什么我首先尝试做的事情不起作用。

这是我的数据模型。我正在寻求建议。

enter image description here

我可以将以下内容作为谓词:

[NSPredicate predicateWithFormat:@"ANY conditions.terrain == %@", aTerrainObject];

工作正常,并返回任何一条建议,其中至少有一个条件具有该地形类型。

然而,当我尝试这样做时,它失败了:

[NSPredicate predicateWithFormat:@"ANY conditions.terrain == nil"];

我想要做的是返回任何一条建议,其中至少有一个条件没有设置地形类型。

但是,以下方法确实有效:

[NSPredicate predicateWithFormat:@"SUBQUERY(conditions, $x, $x.terrain == nil).@count > 0"];

任何人都可以解释为什么在搜索nil时,我无法使用ANY语法?

2 个答案:

答案 0 :(得分:25)

  

任何人都可以解释为什么在搜索nil时,我无法使用ANY语法吗?

是的!这是发生了什么。

[NSPredicate predicateWithFormat:@"ANY conditions.terrain == nil"];

首先,让我们将其分解为适当的左右表达式:

conditions.terrain

这将通过获取SELF对象(Advice实例)并请求valueForKeyPath:@"conditions.terrain"来评估。此keypath的结果将是一个集合。你基本上在做:

Advice *a = ...;
NSSet *conditions = [a conditions];
NSSet *terrains = [conditions valueForKey:@"terrain"];

因此,您有一组(潜在的)Terrain个实例。现在,我们对Objective-C中的集合了解多少?好吧,有一件事,他们不能包含nil。它们只能包含对象。这意味着当它执行谓词的ANY部分时,它将遍历数组中的项目并看到它们都不是nil

因此,你的谓词失败了。我尝试使用其他一些变体(使用[NSNull null]代替nil等),但它们似乎都没有效果。

因此,您使用SUBQUERY来解决此问题似乎与您所获得的一样好。我强烈建议filing a bug详细说明您的期望,并表达您认为这应该有效的原因。

答案 1 :(得分:0)

我相信你不能在查询中使用nil。您应该使用NULL或格式字符串构造,如"ANY conditions.terrain == %@", nil

<击>

让我感到困惑的是你的子查询正在运行......

上述情况不正确,因为NULLNIL可以互换使用。

相反,NSExpression Class Reference确切地给出了您的模式(使用@count)作为首选示例。

您是否检查过地形关系是否可选?