【问题标题】:Core Data predicate crashes when attribute is nil当属性为 nil 时,Core Data 谓词崩溃
【发布时间】:2023-04-04 01:48:01
【问题描述】:

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


我有一个带有birthDate 属性的实体和一个带有以下谓词的提取属性,直接输入到xcdatamodel 文件中:

$FETCH_SOURCE.birthDate > birthDate

这会愉快地返回早于 FETCH_SOURCE 的托管对象列表(发生获取请求的托管对象)。但是birthDate 是可选的,如果FETCH_SOURCE 的birthDate 为nil...

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'

Google 还没有听说过这些错误,所以我认为这是最近的情况。当它是一个字符串被比较是否等价时,问题仍然存在。有没有办法在谓词中解决这个问题,以便正确返回一个空列表?谢谢。

编辑:明确地说,问题是是否可以在 xcdatamodel 文件的谓词中修复此崩溃。

更新:当 NSFetchedPropertyDescription 的关系错误是通过尝试读取有关它的任何内容而触发时,可能会发生崩溃,大概是因为它直到那时才尝试运行谓词。但是它不是 nil,并且可以在不崩溃的情况下检查 nil。

【问题讨论】:

  • Icaro,他们有相似的标题关键字,但完全不同的问题。你是机器人吗? ;)
  • 不只是想帮忙,但那不是很酷! ;) 无论如何,我从最后一个问题的理解是,您可以与 nil 进行比较,但您不能使用 nil 值与某物进行比较,这似乎是我的测试结果,但我会向其他人解释,因为我不这样做'真的不知道为什么!
  • 我明白你的意思,但看起来这个问题是关于在变量参数列表中传递 nil ,这恰好是在格式化谓词时完成的,而不是在实际中使用 nil谓词。相反,它支持我的怀疑,即我的问题是一个新问题,因为 Core Data 在 2014 年 7 月 10 日对谓词“parentFolder == nil”非常满意。
  • 你试过使用birthDate != [NSNull null]

标签: ios swift core-data ios8 nspredicate


【解决方案1】:

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

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;
}

(这些 sn-ps 位于 FETCH_SOURCE 实体的子类的实现文件中)。

【讨论】:

  • 这行得通,虽然不是 xcdatamodel 中的修复,但它是对谓词的修复,它满足我良好结构的强迫症。赏金是你的,除非有人能在赏金日之前改进它......
【解决方案2】:

如果您希望结果包含 nil 值,或者它必须大于或小于某个日期,请使用以下命令:

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

这对我有用。我希望这是你要问的。理解您的问题时遇到了一些问题。

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

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

【讨论】:

  • 当birthDate 为nil 时,这会以与OP 相同的方式崩溃。
  • 添加了一个 tl;dr 和图片,希望能让问题更容易理解。 :)
  • 是的,抱歉,我没有按照 .xcdatamodeld 文件中定义的方式使用谓词。我希望这是一个关于查询的简单修复。我也使用了日期检查,它被允许为零并且日期必须在未来。我会很快检查整个 $FETCH_SOURCE 的事情。
  • 否,如果发生获取请求的托管对象的出生日期为 nil,则它会因相同的错误而崩溃。如果这就是你在谓词中写的全部内容,它甚至会崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
相关资源
最近更新 更多