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

Core data 使用NSFetchedResultsController反映对父对象关系中对象的更改,core-data,nsfetchedresultscontroller,Core Data,Nsfetchedresultscontroller,我有两个实体事件和时间。事件实体与时间实体具有1对多关系,因为每个事件可以执行多次。现在我想在tableView中按时间顺序显示所有事件。因此,我设置了一个fetchedResultsController来获取所有时间对象,根据开始时间对它们进行排序,并使用与事件对象的关系显示事件信息。到现在为止,一直都还不错。但是现在,如果用户在表中标记一个条目,我会将一个事件对象传递给detailViewController,在那里可以编辑事件 问题是现在只有事件实体被标记为已更新。我通过查看NSManag

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

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

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

非常感谢
托马斯

我现在也在做一些类似的更新。这是我处理这个问题的方法

假设我们有对象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回调进行更新。希望这有助于解决您的问题。

我的模型有点不同,但可以很容易地转换为您的模型。
我得到了一个树状结构:

  • 元素
    • 头衔
    • 父母(对一)
  • 文件夹:元素
    • 儿童(对许多人而言)
  • 文件:元素
添加或删除文件时,只有队列中的第一个文件夹会收到有关此更改的通知。当文件标题更改时,不会通知任何文件夹。那么,该怎么办?
我尝试在我的元素类中重写-willChangeValueForKey:和-didChangeValueForKey:

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

- (void)didChangeValueForKey:(NSString *)key
{
    [super didChangeValueForKey:key];
    [self.parent didChangeValueForKey:@"children"];
}
基本上,这是因为父文件夹的一个子文件夹已更改而强制更新。

希望它也能对您起作用。

上面@Jenox的答案似乎是正确的,但最好不要重写这些方法,因为每当子对象上的任何键发生更改时,都会调用这些方法,这可能会影响性能并导致意外的副作用(对我来说确实如此)。可能最好只使用您对子对象进行更改的任何方法调用它们,如下所示:

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

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

我现在尝试的是使用新的userInfo字典手动发布NSManagedObjectContextObjectDidChangeNotifications,其中包括受事件对象更改影响的时间对象。不幸的是,FRC没有做出反应。目前我正在处理一个问题,我想根据关系中某个属性的值在视图中排序,我下面的解决方案还不够。祝你好运FRC总是令人头痛。我有点困惑。在A中定义B属性的setter?使用
keypathsforvaluesafectingvalueforkey
设置依赖项,您觉得如何?就像这里一样,B显然有能力设置它的属性,但是为了方便起见,我添加了一个属性来设置a的属性。在我的情况下,这有助于进入该物业,但对你来说可能完全不同。尽管如此,无论您在哪里设置属性,您都应该能够使用遗嘱,并且确实进行了更改。我认为设置依赖项的方法是个好主意,但在实践中对我来说并不奏效。当我测试将其添加到我的应用程序使用时,这导致了一系列崩溃,风险由你自己承担。FWIW:这似乎是正确的想法,但最好不要覆盖这些方法,而不是用任何方法调用它们来更改子对象,就像这样:苹果的文档清楚地声明“你不应该在子类中重写这个方法”。From:如上所述-覆盖这些方法不是一个好主意。我可以建议您使用类似但更安全的实现更新您的答案吗?i、 e.将所有元素更新包装在一个更新方法中。@JordanSmith重写“setter”的全部目的是不必担心调用其他方法来正确传播更改。此外,只有一个额外的“更新”方法不足以正确发送will/did对的通知。世界肯定需要Swift!