首页 文章

核心数据中的提取属性返回不正确的计数

提问于
浏览
0

我有一个核心数据关系,看起来像这样

ItemA - >> ItemB

其中itemA有很多itemB . 我想使用一个fetched属性,它允许我获取与itemA相关联的所有关联的itemB,其中int32状态属性设置为“2” . 所以我在数据建模器中创建了一个具有以下内容的fetched属性:

fetched属性:completedItem谓词:status == 2 destination:itemB

当我第一次尝试它时,我得到了物品,我认为这一切都很酷并完成,然后我注意到了奇怪的行为,当我看得更近时,它返回的物品没有处理与之相关的物品B的实际数量一个itemA对象 . 甚至更奇怪的是返回类型是NSFaultingMutableArray . 这是一个简单的例子

  • ItemA的itemB为0

  • 对NSSet属性的过滤谓词搜索ItemA的ItemB返回0

  • 获取的属性"completedItem"返回ItemB的4

  • 它返回的类型是NSFaultingMutableArray

这在我脑海里现在很奇怪,真的没有意义 . 有任何想法吗?

更新1:

看来这里列出的fetched属性获取核心数据必须提供的所有ItemB对象,这些对象与谓词匹配,即使它与相关的ItemA没有关联

3 回答

  • 0

    以下是本期所有奇怪的答案:

    1)获取的属性确实没有为ItemA返回ItemB对象 . 为了实现这一点,您必须在获取的属性谓词中添加类似的内容

    status == 2 AND ItemA == $FETCH_SOURCE
    

    2)从Fetched Properties文档中:

    延迟评估获取的属性,然后缓存该属性 . 如果更改了目标实体中的对象,则必须重新评估fetched属性以确保它是最新的 . 您使用refreshObject:mergeChanges:手动刷新属性 - 这会导致在下次触发对象故障时再次执行与此属性关联的获取请求 .

    所以基本上使用refreshObject:mergeChanges手动刷新对象以重新加载fetched属性 . 您可以通过添加刷新方法或对子类NSManagedObject中的KVC get方法进行一些花哨的覆盖来完成此操作 .

    话虽如此,其他人(Rob Booth,Grady Player)通过完全绕过获取的属性来获得其他有效的解决方案 . 虽然这些都是法尔

  • 2

    凯尔,问题是核心数据试图比你聪明 . 如果您不打算使用它们,Core Data不希望用数据存储区中的所有对象填满您的内存 . 因此,不是一直创建真实对象,而是创建“故障” . 错误是真实对象的占位符,当您要求这些对象时,Core Data会在此时移动并填充对象 .

    我最好的猜测是你对ItemA.ItemB属性的搜索没有实现链接对象,所以这就是你回到0集的原因 . 如果您刚刚执行了NSSet * mySet = ItemA.ItemB,我确定您会看到mySet包含正确的对象计数 . 但是对ItemA.ItemB进行计数是将计数消息发送到故障集,从而返回0 .

    当你使用completedItems属性时,CoreData似乎至少做了一些事情来返回正确数量的对象,但还没有返回实际的对象数据 .

  • 0

    让我们使用这个术语:

    我们有一个ClassA的objectA

    我们有一些ClassB的对象(未命名)

    我们已将ClassB对象添加到objectA .

    objectA是对NSManagedObject的子类的引用...当你调用objectA.completeItem时,你要求objectA获取ItemB的集合,这将起作用,因为你正在使用内存中的一个实例 .

    当你创建一个新的NSManagedObjectContext并在其中执行获取时,它不知道你的objectA或它的关系,除非你在执行提取之前执行对objectA的上下文的保存 .

    编辑:

    对于你谓词只过滤掉ItemA所拥有的classB对象,你可以使用一个谓词(假设itemA是你的ItemA cpmletedItem关系的反转)

    [NSPredicate predicateWithFormat: @"itemA = %@",itemA];

相关问题