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

时间:2011-12-13 20:47:55

标签: ios macos core-data ios5 fetched-property

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

ItemA - >> ItemB

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

fetched属性:completedItem 谓词:status == 2 目的地:itemB

当我第一次尝试时,我得到了物品,我认为这很酷并完成,然后我注意到奇怪的行为,当我仔细观察它返回的物品没有什么可以处理物品B的实际数量与itemA对象相关联。甚至更奇怪的是返回类型是NSFaultingMutableArray。这是一个简单的例子

  • ItemA有0个itemB
  • 对NSSet属性的过滤谓词搜索ItemA的ItemB返回0
  • fetched属性“completedItem”返回ItemB的4个
  • 它返回的类型是NSFaultingMutableArray

现在这在我脑海中只是奇怪,真的没有意义。任何想法?

更新1:

此处列出的fetched属性显示所有 ItemB对象,核心数据必须提供与谓词匹配的对象,即使它与相关ItemA无关

3 个答案:

答案 0 :(得分:2)

这是这个问题中所有奇怪的答案:

1)获取的属性确实没有为ItemA返回ItemB对象。为了实现这一点,您必须在fetched properties predicate

中添加类似的内容
status == 2 AND ItemA == $FETCH_SOURCE

2)从Fetched Properties文档:

  

一个fetched属性被懒惰地评估,然后被缓存。

     

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

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

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

答案 1 :(得分:0)

让我们使用这个术语:

我们有一个ClassA的objectA

我们有一些ClassB

的对象(未命名)

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

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

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

编辑:

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

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

答案 2 :(得分:0)

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

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

当你使用completedItems属性时,CoreData似乎至少要做一些事情来返回正确数量的对象,但不是实际的对象数据。