首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UndoManager与多重MOC

UndoManager与多重MOC
EN

Stack Overflow用户
提问于 2014-02-14 14:08:23
回答 1查看 479关注 0票数 3

我有3个MOC。

  1. MainThread MOC用于显示东西(使用undomanager)
  2. 背景-保存MOC以将数据保存到磁盘(连接到存储)
  3. Backgorund-更新MOC,从服务器下载数据,解析数据,然后保存。

他们是亲子关系。

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

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

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

代码语言:javascript
复制
 //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

块看起来是这样的:

代码语言:javascript
复制
[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];
        }];

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-14 19:12:02

首先,关于已发布代码的一些基本观察。

  1. 你应该只在绝对必要的时候使用performBlockAndWait .这几乎从来都不是。
  2. 您正在对子上下文调用performBlockAndWait,而在父上下文的performBlockAndWait中调用。你应该永远不要那样做。
  3. 使用performBlockAndWait在具有专利上下文的上下文中调用save:几乎可以保证不执行您认为它所做的事情。它所做的就是保存到父上下文。
  4. 在同一个上下文中的performBlockAndWait中调用performBlockAndWait。这没什么不对的,因为那个电话是重来的。然而,这是另一条线索,即您的CD堆栈管理有问题。

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

在您的情况下,我建议对您的MOC等级进行更改。保持私有队列MOC作为主队列MOC的父队列。这允许您的DB更改异步执行。没什么不对的。请记住,您必须将save:调用级联到父级或调度保存,因为保存主MOC只会将其数据复制到父上下文中,而不会触及底层数据库。

然而,我会以这个背景MOC作为主要MOC的一个子代来删除它。现在,您根本不必担心撤销管理器,您可以不去管它。

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

现在,如何处理正在执行某种类型的异步更新(可能来自某个web服务)的背景上下文。我建议要么:

  1. 将它的父级设置为与主MOC相同。您需要刷新主MOC以进行父级更改。这有一个缺点:对数据库的任何更新都是通过同一个父MOC同步的,给主MOC留出了更多的等待机会。
  2. 将其直接连接到持久性存储协调器,并使用通知合并更改。

最后,重新考虑您的设计,看看您是否可以通过异步调用。实际上,您应该能够通过调用performBlock,而只在极其罕见的情况下调用performBlockAndWait

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21781563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档