2010-02-02 37 views
4

我有一个核心数据iPhone应用程序,它显示Subscription实体,其任何items不是read。换句话说,我构建一个谓词是这样的:带有基于依赖属性的谓词的NSFetchedResultsController

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

尽管这适用于初始获取,它不会影响Subscription实体,当我修改Item,所以NSFetchedResultsController从未重新评估的Subscription实体。什么是更好的结构化方法,以便在项目的read属性被设置时更新Subscription实体?

我曾尝试在Subscription创建一个属性unreadCount和使用keyPathsForValuesAffectingUnreadCount返回包含items.read一组。我没有想到这会起作用,但事实并非如此。我从_NSFaultingMutableSet得到一个例外,告诉我read密钥不受支持。

回答

2

我看到两个解决方案:

  1. 当你修改项目有获取的成果控制器进行再次提取和重新加载表视图。
  2. 为订阅添加属性(例如您的unreadCount或布尔hasUnreadItems)并保持其正确更新。在抓取的结果控制器中使用此属性。

你可以得到一套未读项目名为“aSubscription”像这样订阅:

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

我当时希望有人能够进入并提供一些我没有想到的精彩方法,但我怀疑你是对的,特别是在解决方案2中。我想我会让'unreadCount'成为一个“真正的”属性,并在物品更新时更新它。 – Alex 2010-02-02 20:24:03

+0

为了您的更新,我最终为'Subscription'添加了属性,以便'NSFetchedResultsController'只需要观察一个实体。奇怪的是,除非我在'managedObjectContextObjectsDidChange:'中的更新对象中出错,否则'NSFetchedResultsController'仍然看不到它们。这有点混乱,我很关心单个对象在一组对象中的性能问题,但现在它确实有效。 – Alex 2010-02-03 14:44:18

+0

奇怪。你如何更新新的财产? – gerry3 2010-02-03 18:11:24

0

对不起,我应该仔细阅读问题。

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

+0

是的,如果订阅变化,您将会收到通知。但修改'Item'不会修改'Subscription',因此提取的结果控制器不会看到任何更改以通知委托人。 – Alex 2010-02-02 16:43:10

+0

完全重新载入表视图的唯一缺点是你失去了一些状态,选择状态。我确信重新加载不会造成性能损失,但我不想放弃这一点UI反馈。 – Alex 2010-02-02 19:12:53

3

您遇到其中的通知没有收到与NSFetchedResultsController错误的(或评估?)相关实体的财产变化。

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

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

我的经验只能达到一对一的关系。当你只改变其中一个关键字时,我不清楚你将如何处理你的一对多关系。这可能工作:

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

这应该发送的关系(subscription.items)是由NSFetchedResultsController正在观看的subscriptions对象改变的通知。

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