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

发布于 2024-09-29 00:59:21 字数 496 浏览 1 评论 0原文

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

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

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

多谢 托马斯

I have two entities event and time. The event entity has a 1 to many relationship to time entities as each event can be performed multiple times. Now I want to display all the events chronologically in a tableView. So I set up a fetchedResultsController to fetch all time objects, sort them according to the start time and display the event information by using the relationship to the event object. So far so good. But now if the user tabs an entry in the table I pass an event object to the detailViewController where the event can be edited.

The problem is that now only the event entity is marked as updated. I found this out by looking at the userInfo directory of the NSManagedObjectDidChange notification. In consequence the delegate methods on the FRC are not fired as no time objects have been changed.

How can I manually mark a time object as changed to make the FRC recognize the changes and update the cells accordingly? I tried firing the KVO methods willChangeValueForKey and didChangeValueForKey but it did not work so far.

Thanks alot
Thomas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

总攻大人 2024-10-06 00:59:21

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

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

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

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

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

基本上,这样做是强制父文件夹更新,因为它的子文件夹之一发生了更改。
希望它也适合你。

My model is a little different, but it can easily be translated to your one.
I got a tree-like structure:

  • Element
    • title
    • parent (to-one)
  • Folder : Element
    • children (to-many)
  • File : Element

When a file gets added or deleted, only the first folder in the queue up gets notified about this change. When a file's title changes, not a single folder would get notified. So, what to do?
I tried overriding -willChangeValueForKey: and -didChangeValueForKey: in my Element class.

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

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

Basically, what this does is forcing the parent folder to update because one of its children changed.
Hope it works for you, too.

春风十里 2024-10-06 00:59:21

我现在也在进行一些类似类型的更新。这是我解决问题的方法。

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

I'm working through some similar types of updates right now as well. Here's the way I approached the problem.

Let's say we have object A, which relates to object B. B has a property C. We want changes to property C to be reflected in FRCs that use A as the fetched object. What I did to make this happen was to define an accessor to property C from object A:

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

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

This allowed my cells to update based on FRC callbacks with type NSFetchedResultsChangeUpdate. Hopefully this helps solve your problem.

勿忘初心 2024-10-06 00:59:21

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

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

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

The answer above from @Jenox appears to be the right idea, but it's best to not override those methods as they're called whenever any key is changed on the child object and will probably impact performance and cause unexpected side-effects (it did for me). Probably best to just call them in whatever method you make the changes to the child object in, like this:

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

Note that updateFromDictionary is one of my methods, not a system method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文