1

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

项目A ->> 项目B

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

获取的属性:completedItem 谓词:状态 == 2 目的地:itemB

当我第一次尝试时,我拿回了物品,我认为这一切都很酷并且完成了,然后我注意到奇怪的行为,当我仔细观察时,它返回的物品与相关的 itemB 的实际数量无关一个 itemA 对象。更奇怪的是返回类型是 NSFaultingMutableArray。这是一个简单的例子

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

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

更新 1:

似乎此处列出的 fetched 属性获取了核心数据必须提供的与谓词匹配的所有ItemB 对象,即使它与相关的 ItemA 没有关联

4

3 回答 3

3

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

1) 获取的属性确实没有为 ItemA 返回 ItemB 对象。为了发生这种情况,您必须在 fetched properties 谓词中添加类似的内容

status == 2 AND ItemA == $FETCH_SOURCE

2)从获取的属性文档中:

获取的属性被延迟评估,随后被缓存。

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

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

话虽如此,这里的其他人(Rob Booth,Grady Player)通过完全绕过获取的属性有其他有效的解决方案。虽然这些都很少

于 2011-12-14T04:48:57.463 回答
0

让我们使用这个术语:

我们有一个 ClassA 的 objectA

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

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

objectA 是对 NSManagedObject 的子类的引用...当您调用 objectA.completeItem 时,您是在向 objectA 询问一组 ItemB,这将起作用,因为您正在使用内存中的一个实例。

当您创建一个新的 NSManagedObjectContext 并在其中执行提取时,它对您的 objectA 或其关系一无所知,除非您在执行提取之前对 objectA 的上下文执行保存。

编辑:

对于您的谓词仅过滤掉 ItemA 拥有的 classB 对象,您可以使用类似的谓词(假设 itemA 与您的 ItemA cpmlletedItem 关系相反)

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

于 2011-12-13T20:54:35.753 回答
0

凯尔,问题在于 Core Data 正试图变得比你更聪明。如果您不打算使用它们,Core Data 不想用数据存储中的所有对象填满您的内存。因此,它不是一直创建真实对象,而是创建“故障”。故障是真实对象的占位符,当您请求这些对象时,Core Data 会在那个时候填充这些对象。

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

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

于 2011-12-13T22:35:31.987 回答