属性为零时,核心数据谓词崩溃

时间:2015-06-22 22:33:35

标签: ios swift core-data ios8 nspredicate

tl; dr:如果birthDate为nil,请在此输入一些不会崩溃的内容:

xcdatamodel screenshot

我有一个具有birthDate属性的实体和一个带有以下谓词的fetched属性,直接键入xcdatamodel文件:

$FETCH_SOURCE.birthDate > birthDate

这很高兴地返回一个早于FETCH_SOURCE(发生获取请求的托管对象)的托管对象列表。但birthDate是可选的,如果FETCH_SOURCE的birthDate为零......

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'can't use NULL on left hand side'

请注意,如果要比较的对象的属性为nil,则可以正常运行。如果我交换谓词的参数:

birthDate < $FETCH_SOURCE.birthDate

...我得到了同样的错误。试图测试它为零:

(birthDate != nil AND birthDate < $FETCH_SOURCE.birthDate)

...给出...

'NSInvalidArgumentException', reason: 'illegal comparison with NULL'
谷歌没有听说过这些错误,所以我认为这是近期的事态。当它被比较为等价或其他什么时,问题仍然存在。有没有办法在谓词中修复它,所以它正确返回一个空列表?感谢。

编辑:要清楚,问题是是否可以在xcdatamodel文件的谓词中修复此崩溃。

更新:当NSFetchedPropertyDescription的关系错误通过尝试读取它的任何内容而触发时,特别会发生崩溃,可能是因为它在此之前没有尝试运行谓词。但它并不是真的,可以检查nil而不会崩溃。

2 个答案:

答案 0 :(得分:6)

我找不到任何方法来修改fetched属性的谓词以避免此错误,但一种解决方法是为olderHeroes fetched属性实现自定义getter。如果birthDate为零,则应该返回一个空数组。

var olderHeroes: NSArray {
    var array : NSArray
    if self.birthDate == nil {
        array = NSArray()
    } else {
        self.willAccessValueForKey("olderHeroes")
        array = self.primitiveValueForKey("olderHeroes") as! NSArray
        self.didAccessValueForKey("olderHeroes")
    }
    return array
}

或在Objective-C中:

-(NSArray *)olderHeroes {
    NSArray *array;
    if (self.birthDate == nil) {
        array = [NSArray array];
    } else {
        [self willAccessValueForKey:@"olderHeroes"];
        array = [self primitiveValueForKey:@"olderHeroes"];
        [self didAccessValueForKey:@"olderHeroes"];
    }
    return array;
}

(这些片段在FETCH_SOURCE实体的子类的实现文件中)。

答案 1 :(得分:2)

如果您希望结果包含零值或者必须大于或小于特定日期,请使用以下内容:

((birthDate == nil) OR (birthDate < %@))

这对我有用。我希望这就是你所要求的。理解你的问题有点麻烦。

如果您要求检查您在谓词中传递的变量,可能会执行以下操作(未经测试):

(($FETCH_SOURCE.birthDate == nil && birthDate == nil) OR ($FETCH_SOURCE.birthDate < birthDate))