gpt4 book ai didi

ios - UndoManager 和多个 MOC

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:06:31 25 4
gpt4 key购买 nike

我有 3 个 MOC。

  1. MainThread MOC 显示内容(使用 undomanager)
  2. 后台保存 MOC 以将数据保存到光盘(连接到存储)
  3. Backgorund-update MOC 从服务器下载数据,解析并稍后保存

它们是父子关系。

  1. 后台更新 -> 1. MainThread -> 2. 后台保存(存储)

现在,当我从后台下载数据时,我需要在主线程上禁用 undomanager,这样它们就不会撤消 - 这可能是用户正在同时编辑某些内容的情况。

现在的问题是这是否正确。我在后台更新线程中有该代码

 //create child background context which is child of 1. MainThread
NSManagedObjectContext* context = [[AppManager sharedAppManager] createChildManagedObjectContext];
//I'M DOING ALL CHANGES ON DATA HERE
[context.parentContext.undoManager disableUndoRegistration]; //disable undo on main thread
[context save:nil]; //save changes to background thread
[context.parentContext save:nil]; //save changes to main thread
[context.parentContext processPendingChanges]; //process changes on main thread
[context.parentContext.parentContext save:nil]; //save data to disc on 3. save-thread
[context.parentContext.undoManager enableUndoRegistration]; //enable undo again

block 看起来像这样:

[context.parentContext performBlockAndWait:^{
[context.parentContext.undoManager disableUndoRegistration];

[context performBlockAndWait:^{
[context save:nil];
}];

[context.parentContext save:nil];
[context.parentContext processPendingChanges];

[context.parentContext performBlockAndWait:^{
[context.parentContext.parentContext save:nil];
}];

[context.parentContext.undoManager enableUndoRegistration];
}];

我问是因为偶尔我会遇到一些不一致的崩溃,而我真的找不到原因。

最佳答案

首先,对发布的代码进行一些基本观察。

  1. 您应该只在绝对必要时才使用 performBlockAndWait...这几乎从不。

  2. 您在子上下文中调用 performBlockAndWait,而在父上下文中调用 performBlockAndWait。你不应该永远那样做。

  3. 使用 performBlockAndWait 在具有专利上下文的上下文中调用 save: 几乎可以保证不会按照您的想法行事。它所做的只是保存到父上下文。

  4. 您在同一上下文中的 performBlockAndWait 中调用 performBlockAndWait。这没什么问题,因为该调用是可重入的。但是,这是另一个线索,表明您的 CD 堆栈管理存在问题。

现在,一些可能有帮助的建议。

在您的情况下,我建议更改您的 MOC 层次结构。将专用队列 MOC 作为主队列 MOC 的父级。这允许您的数据库更改异步完成。那里没有错。请记住,您必须将 save: 调用级联到父级或安排一次保存,因为保存主 MOC 只会将其数据复制到堆栈上到父级上下文,而不会触及底层数据库.

但是,我会采用该背景 MOC 并将其作为主要 MOC 的子项删除。现在,您完全不必担心撤消管理器,您可以不用管它。

说到撤消管理器,我发现最好的撤消管理器是子上下文。我只想创建一个上下文,它是主上下文的子上下文,在其中进行所有更改。如果放弃更改,只需删除上下文。一切都被撤销了。您可以在该上下文中安装撤消管理器以进行增量撤消管理。

现在,如何处理正在执行某种类型的异步更新(可能来自某些 Web 服务)的后台上下文。我建议:

  1. 将其父级设置为与主 MOC 相同。您将需要刷新主 MOC 以更改父级。这样做的缺点是,对数据库的任何更新都是通过同一个父 MOC 同步的,为主 MOC 留下更多等待获取的机会。

  2. 将其直接连接到持久存储协调器,并使用通知合并更改。

最后,重新审视您的设计,看看您是否可以使用异步调用。您真的应该能够避免调用 performBlock,并且只在极少数情况下调用 performBlockAndWait

关于ios - UndoManager 和多个 MOC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21781563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com