【问题标题】:Core Data, NSPredicate and to-many key核心数据、NSPredicate 和多对多键
【发布时间】:2010-11-12 22:55:32
【问题描述】:

我有一个核心数据模型,其中一个任务实体包含一个可选的多对多关系排除事件。 excludeOccurrences 的属性之一是 start,它是一个 NSDate 对象。 ExcludedOccurrence 实体与 Task 实体具有相反的强制一对一关系。

为了获取指定日期的任务,我需要确保指定日期不会作为任何 ExcludedOccurrence 实体的开始属性出现。因此,我尝试使用的子谓词之一是

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today];

tod​​ay 是今天的 NSDate 对象,仅包括日、月和年组件。所有排除的事件开始属性还仅包括日、月和年组件。

虽然这应该没问题,但至少阅读 Core Data 和 NSPredicate 的文档,我收到以下错误消息:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“不支持的谓词”

如果我使用等价谓词

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today];

没有抛出异常,但是代码没有按预期工作:今天发生的不应该被排除的事件被排除了。

我也不确定如何测试excludedOccurrences == nil 的情况:以下谓词

NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"];

在运行时导致异常

这里不允许使用多对多键

但是,由于excludedOccurrences关系是可选的,所以我还需要测试它是否为nil。

我该如何处理?提前谢谢你。

【问题讨论】:

    标签: iphone core-data nspredicate


    【解决方案1】:

    要测试空关系,您应该将一对多键的计数与零进行比较。

    [NSPredicate predicateWithFormat:@"excludedOccurrences.@count == 0"];
    

    至于您的子谓词,请注意,您只能在最终谓词中使用 ALLANY 修饰符之一,尽管您可以在整个谓词中多次使用该修饰符。

    不行ANY foo.bar = 1 AND ALL foo.baz = 2
    好的:ANY foo.bar = 1 AND !(ANY foo.baz != 2)

    【讨论】:

    • 你的空关系解决方案对我来说崩溃了。
    • 很抱歉,谓词格式已修复。当这篇文章发布时,我从不费心去测试我的假设,显然其他人也没有。
    • 令人难以置信的是,我一直在寻找对空关系进行一对多测试的时间。很高兴你把它贴在这里!
    • 谢谢。让我离开了一个地方。
    • 谢谢!为什么文档告诉我在不工作时使用'array [SIZE]'?!没有在任何地方提及“@count”。
    【解决方案2】:

    在大家的帮助下,我终于为我的场景确定了正确的谓词。 看起来 NSDate 对象被处理为双精度,但是,双精度永远不会像 3.7,它总是像 3.0 因此,以下谓词在我的测试中正确工作:

    NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences.@count == 0 || (excludedOccurrences.@count > 0 && NONE excludedOccurrences.start == %@))",thisDate];
    

    其中 thisDate 是一个 NSDate 对象,仅包含日、月和年组件(与 ExcludedOccurrence 实体的 start 属性一样。

    按照 Apple 的一些人的建议,基本上使用 @count 聚合运算符来测试空关系。

    再次感谢您的帮助。 我仍然观察到文档在几个部分存在缺陷(尤其是在它说 ALL 工作正常,而实际上它根本不起作用的地方)。

    【讨论】:

      【解决方案3】:

      因此,要测试非空关系,这实际上是有效的:

      [NSPredicate predicateWithFormat:@"relationship.@count != 0"]
      

      Ashley Clark 给出的解决方案让我崩溃了,因为我给出了“此处不允许使用对多键”

      【讨论】:

      • 我已经更正了我的答案,不知道我写的时候在想什么。过失。
      【解决方案4】:

      在 swift 2 中,类似:

      request.predicate = NSPredicate(format: " relationship.@count != 0")
      

      【讨论】:

        猜你喜欢
        • 2012-03-08
        • 2011-02-18
        • 1970-01-01
        • 2011-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多