带有基于依赖属性的谓词的 NSFetchedResultsController

Posted

技术标签:

【中文标题】带有基于依赖属性的谓词的 NSFetchedResultsController【英文标题】:NSFetchedResultsController with predicate based on dependent property 【发布时间】:2010-02-02 16:27:32 【问题描述】:

我有一个 Core Data iPhone 应用程序,它显示Subscription 实体,其中任何items 不是read。换句话说,我构造了一个这样的谓词:

[NSPredicate predicateWithFormat:@"ANY items.read == NO"]

虽然这适用于初始提取,但当我修改 Item 时它不会影响 Subscription 实体,因此 NSFetchedResultsController 永远不会重新评估 Subscription 实体。有什么更好的方法来构建它,以便在设置项目的 read 属性时更新 Subscription 实体?

我确实尝试在Subscription 上创建属性unreadCount 并使用keyPathsForValuesAffectingUnreadCount 返回包含items.read 的集合。我没想到这会奏效,也没有。我收到了来自_NSFaultingMutableSet 的异常,告诉我不支持read 键。

【问题讨论】:

【参考方案1】:

您遇到了NSFetchedResultsController 的错误,其中未收到(或评估?)相关实体的属性更改的通知。

在这种情况下,itemsread 属性不会被“监视”以进行更改。

您可以通过伪造关系中items 的更改来解决此问题,而不是重新构建。即当你更改item.read时,也要假装更改item

我的经验仅限于一对一的关系。当您只更改多个键中的一个键时,我不清楚您将如何处理您的一对多关系。这可能有效:

thisItem.read = [NSNumber numberWithBool:NO];
[thisItem.subscription willChangeValueForKey:@"items"];
[thisItem.subscription didChangeValueForKey:@"items"];

这应该发送一个通知,告知NSFetchedResultsController 正在监视的subscriptions 对象上的关系 (subscription.items) 正在发生变化。

我可以提供一个完美运行的一对一关系案例的工作示例。

【讨论】:

【参考方案2】:

我看到了两种解决方案:

    当您修改项目时,获取的结果控制器会再次执行获取并重新加载表格视图。 向 Subscription 添加一个属性(例如您的 unreadCount 或布尔型 hasUnreadItems)并保持正确更新。在获取的结果控制器中使用此属性。

您可以像这样获取名为“aSubscription”的订阅的未读项目集:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"read == NO"];
NSSet *unreadItems = [aSubscription.items filteredSetUsingPredicate:pred];

【讨论】:

我希望有人会突然介入并提供一些我没有想到的绝妙方法,但我怀疑你是对的,尤其是解决方案 #2。我想我只需将unreadCount 设为“真实”属性,并在项目更新时对其进行更新。 只是给你一个更新,我最终将属性添加到Subscription,以便NSFetchedResultsController 只需要观察一个实体。不过奇怪的是,除非我在managedObjectContextObjectsDidChange: 中更新了对象,否则NSFetchedResultsController 仍然看不到它们。这有点杂乱无章,我担心单独在一堆对象中出现故障会影响性能,但它现在确实有效。 很奇怪。您如何更新新属性? 您是将属性添加到子类还是实际将属性放入模型中的核心数据实体中?听起来你只是把它放在子类中,正如你所见,它不能很好地工作。 gerry3 的建议是在模型本身的实体中添加一个属性并保持更新。【参考方案3】:

抱歉,我应该仔细阅读这个问题。

我通过设置 NSFetchedResultsController 缓存然后在 viewDidAppear: 方法中刷新我的 UITableView 来解决非常相似的情况。我有一个非常小的数据集,频繁刷新数据并没有明显的性能损失。

【讨论】:

是的,如果Subscription 发生变化,您将收到通知。但是修改Item 不会修改Subscription,因此获取的结果控制器看不到任何通知代理的更改。 完全重新加载表格视图的唯一缺点是您会丢失一些状态,例如选择状态。我确信重新加载的频率不会降低,不会造成性能损失,但我不想放弃那一点 UI 反馈。

以上是关于带有基于依赖属性的谓词的 NSFetchedResultsController的主要内容,如果未能解决你的问题,请参考以下文章

包含带有谓词的属性时的异常

NSFetchedResultsController 我在数组中使用带有属性的谓词?

CoreData fetch 基于谓词添加属性

带有函数参数的 CoreData 谓词

核心数据:基于谓词的验证

带有谓词的 ios 核心数据错误