使用绑定时如何使子 NSManagedObjectContext 保持最新

Posted

技术标签:

【中文标题】使用绑定时如何使子 NSManagedObjectContext 保持最新【英文标题】:How to keep a child NSManagedObjectContext up to date when using bindings 【发布时间】:2013-07-09 05:20:00 【问题描述】:

我将NSManagedObjectContext 设置为NSPrivateQueueConcurrencyType,我大部分时间都在我的应用程序中使用它。

除此之外,我还使用NSMainQueueConcurrencyType 创建了一个子 MOC,用于可可绑定(我听说绑定不适用于私有队列 MOC)。我已经将一些ObjectControllers 和ArrayController 绑定到这个子上下文。我非常希望将孩子保留在主队列中,而不是交换 MOC 队列类型。

当我通过 UI 对绑定对象进行更改时,这些更改不会传播到父上下文。当我对父上下文进行更改时,它们不会过滤到 Object/ArrayControllers。

我怎样才能做到这一点?是否有一个设置会告诉 Object/ArrayControllers 适当地刷新他们的上下文并在他们进行更改时保存它?

【问题讨论】:

【参考方案1】:

要将更改带给父级,您需要保存子级。如果要持久保存更改,还需要在此之后保存父级。

[child save:&error];
[parent performBlock:^
    [parent save:&parentError];
];

要将更改从父级带到子级,您需要使用父级NSManagedObjectContextDidSaveNotification 的通知方法合并更改或在子级上下文中重新获取。在您的情况下,合并可能会更好。

- (void)managedObjectContextDidSave:(NSNotification *)notification 
    // Here we assume that this is a did-save notification from the parent.
    // Because parent is of private queue concurrency type, we are
    // on a background thread and can't use child (which is of main queue
    // concurrency type) directly.
    [child performBlock:^
        [child mergeChangesFromContextDidSaveNotification:notification];
    ];

【讨论】:

这是否意味着每次我通过父 MOC 调整对象的属性时,我都需要调用它的保存方法以传播更改?当它们进入持久存储时,这不会让事情变慢吗? 你的父上下文是私有队列并发类型。您在那里所做的一切,包括保存,都将在后台队列中运行。它不会阻塞你的主线程,但它会锁定上下文和持久存储协调器,但这对你来说可能不是问题。 谢谢,这是一个非常有用的答案。我连接了适当的 IBActions 以在需要时触发子保存,其余的非常简单。 我无法在子上下文中重新获取工作,但合并更改可以。有谁知道是什么原因造成的? 究竟是什么不工作?例如,您在子级中获取对象,然后在父级中更新它(更改某些属性),然后在子级中再次获取。因为该对象已经是一个完全实现的对象,所以第二次 fetch 不会触及它,它只是以其当前状态返回它。这就是 Core Data 的工作原理。它不会自动触及完全实现的对象。但是,当您调用 -mergeChangesFromContextDidSaveNotification: 时,对象的属性将被更新,因为您手动要求合并。

以上是关于使用绑定时如何使子 NSManagedObjectContext 保持最新的主要内容,如果未能解决你的问题,请参考以下文章

如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?

如何根据组合框选择使子表单显示数据?

如何以可在绑定中访问的可重用方式修改 NSManagedObject 类的行为?

使用 NSManagedObject 子类将 NSPopupButton 绑定到 NSArrayContraller

展开 UITableViewCell 时如何使子视图保持相同大小

如何使子列在滚动时跟随父行