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

Gor*_*tch 13 core-data nsfetchedresultscontroller

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

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

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

非常感谢托马斯

Chr*_*orr 7

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

  • 元件
    • 标题
    • 父母(对一)
  • 文件夹:元素
    • 孩子(对多)
  • 文件:元素

添加或删除文件时,只有队列中的第一个文件夹会收到有关此更改的通知.当文件的标题更改时,不会通知单个文件夹.那么该怎么办?
我尝试覆盖-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"];
}
Run Code Online (Sandbox Code Playgroud)

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

  • Apple的文档明确指出"你不应该在子类中覆盖这个方法".来自https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/index.html#//apple_ref/occ/instm/NSObject/willChangeValueForKey: (2认同)

Tah*_*ine 5

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

假设我们有对象 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;
}
Run Code Online (Sandbox Code Playgroud)

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


Ben*_*son 5

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

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

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