使用NSFetchedResultsController反映父对象中关系中对象的更改

时间:2010-10-24 20:37:00

标签: core-data nsfetchedresultscontroller

我有两个实体事件和时间。事件实体与时间实体具有1对多的关系,因为每个事件可以多次执行。现在我想在tableView中按时间顺序显示所有事件。所以我设置了一个fetchedResultsController来获取所有时间对象,根据开始时间对它们进行排序,并通过使用与事件对象的关系来显示事件信息。到现在为止还挺好。但是现在如果用户在表格中选中一个条目,我会将一个事件对象传递给detailViewController,在那里可以编辑事件。

问题是现在只将事件实体标记为已更新。我通过查看NSManagedObjectDidChange通知的userInfo目录找到了这个。因此,FRC上的委托方法不会被触发,因为没有时间对象被更改。

如何手动将时间对象标记为已更改,以使FRC识别更改并相应更新单元格?我尝试触发KVO方法willChangeValueForKeydidChangeValueForKey,但到目前为止它没有用。

非常感谢 托马斯

3 个答案:

答案 0 :(得分:7)

我的模型有点不同,但很容易翻译成你的模型 我有一个树状的结构:

  • 元素
    • 标题
    • parent(to-one)
  • 文件夹:元素
    • 儿童(对许多人)
  • 文件:元素

添加或删除文件时,只有队列中的第一个文件夹会收到有关此更改的通知。当文件的标题发生更改时,不会通知单个文件夹。那么,该怎么办?
我尝试覆盖-willChangeValueForKey:和-didChangeValueForKey:在我的Element类中。

- (void)willChangeValueForKey:(NSString *)key
{
    [super willChangeValueForKey:key];
    [self.parent willChangeValueForKey:@"children"];
}

- (void)didChangeValueForKey:(NSString *)key
{
    [super didChangeValueForKey:key];
    [self.parent didChangeValueForKey:@"children"];
}

基本上,这样做会强制父文件夹更新,因为其中一个子项已更改 希望它也适合你。

答案 1 :(得分:5)

@Jenox的上述答案似乎是正确的想法,但最好不要覆盖这些方法,因为只要在子对象上更改了任何键,它们就会被调用,并且可能会影响性能并导致意想不到的副作用(它对我有用)。可能最好用你对子对象进行更改的任何方法来调用它们,如下所示:

- (void)updateFromDictionary:(NSDictionary *)aDictionary {
    [myParentModel willChangeValueForKey:@"myChildObject"];
    [super updateFromDictionary:aDictionary];
    [myParentModel didChangeValueForKey:@"myChildObject"];
}

请注意,updateFromDictionary是我的方法之一,而不是系统方法。

答案 2 :(得分:4)

我现在正在处理一些类似的更新。这是我解决问题的方式。

假设我们有对象A,它与对象B有关.B具有属性C.我们希望对属性C的更改反映在使用A作为获取对象的FRC中。我做到这一点的方法是从对象A定义属性C的访问器:

//A.m
- (void)setC:(int)cValue {
  [self willChangeValueForKey:@"b"];
  self.b.c = cValue
  [self didChangeValueForKey:@"b"];
}

- (int)c {
  return self.b.c;
}

这允许我的单元格基于类型为NSFetchedResultsChangeUpdate的FRC回调进行更新。希望这有助于解决您的问题。