Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 核心数据多级父-子上下文_Ios_Objective C_Core Data_Nsmanagedobjectcontext - Fatal编程技术网

Ios 核心数据多级父-子上下文

Ios 核心数据多级父-子上下文,ios,objective-c,core-data,nsmanagedobjectcontext,Ios,Objective C,Core Data,Nsmanagedobjectcontext,在我的应用程序中,我有显示事件列表的UITableViewController。此控制器使用ManagedObjectContext,比如说ParentContext。现在,如果选择了任何事件,则会显示详细视图控制器,用户可以在其中编辑事件的详细信息。所以我创造了一个儿童环境,比如 类型为“NSPrivateQueueConcurrencyType”的ChildContext ChildContext,其父上下文为“ParentContext”。 我的代码是: NSManagedObject

在我的应用程序中,我有显示事件列表的
UITableViewController
。此控制器使用ManagedObjectContext,比如说
ParentContext
。现在,如果选择了任何事件,则会显示详细视图控制器,用户可以在其中编辑事件的详细信息。所以我创造了一个儿童环境,比如

类型为“NSPrivateQueueConcurrencyType”的ChildContext

ChildContext,其父上下文为“ParentContext”。

我的代码是:

  NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
  childContext.parentContext = self.context ;
现在又有一些字段和关系需要进一步深入。所以我为新的视图控制器创建了另一个ChildContext,比如

类型为“NSPrivateQueueConcurrencyType”的上下文

父上下文为“ChildContext”的上下文

此过程用于另一个级别(从父级(tableView)到子级总共4个级别)


我的实体看起来像这样

EntityA           -- ( Edit View Controller  - uses ChildContext )
 |
 |- Field1
 |
 |- Field2
 |
 |- RelationShip (1 to Many ) - ( Relationship Add / Edit View Controller - uses GrandChildContext )
     |
     |- Field1
     |    .
     |    .
     |- Field3
     |
     |- Relationship ( 1 to Many ) - ( Relationship Add / Edit View Controller - uses GrandGrandChildContext )
            |
            |- Field1
            |
            |- Field2
这是使用父子上下文的正确方法吗?因为在某个时间点上,我将拥有1个NSMainQueueConcurrencyType MOC和3个NSPrivateQueueConcurrencyType MOC

如果不是呢?还有别的办法吗

太多的子上下文是否会影响应用程序的性能

最初,我使用属性和NSArray来管理用户输入的数据,当用户点击“完成”按钮时,我将更新/创建托管对象。但这是一项乏味的工作,它使我的视图控制器变脏了。因此,我切换到父子上下文,这非常容易保存/放弃更新


谢谢

对于嵌套的托管对象上下文的最佳用例,可能有一些混淆。对于您的情况,我建议只使用一个上下文

从阵列等移动到核心数据是一个非常好的主意。现在释放对象图的真正威力和简单性。尽量使事情简单

为了向下搜索,只需将上下文传递给子视图控制器。您的子视图控制器获取的结果控制器可以使用与父视图控制器相同的上下文。许多Apple代码示例都使用这种模式


您需要上下文的唯一时间是您是否真的需要并发性。这里的情况似乎根本不是这样。检索数据后,将显示子视图控制器的新界面。如果这需要太长时间(例如,因为数据来自web服务),则显示某种“请等待”界面,并在数据检索完成后显示完整的界面。很可能这不是您的场景。

您可能对多个子上下文有点过火,但只有一点点,而且您的一般方法是合理的。MOC(托管对象上下文)是一个相当轻量级的对象

我喜欢您的方法,即在每个视图控制器/场景中,对应用于该场景的MOC有一个明确的引用

有时,将MOC视为一个会话或草稿行是有帮助的。匹配不是在主运行中心和实体之间,而是在主运行中心和逻辑工作单元之间

如果您的某个向下钻取标记了用户可能想要放弃/取消的某个编辑任务的开始,那么现在正是剥离子MOC并将其传递给新视图的好时机。如果需要,您可以回滚:甚至可以在您回到起点时放弃MOC


另一方面,如果您只是为静态信息编写一个查看器,那么只需使用一个MOC。在这种情况下,没有必要或受益于使用更多

如果您查看wwdc 2012视频核心数据最佳实践会话214,它将展示如何使用父上下文和子上下文来显示详细视图控制器。我使用相同的技术,所以如果用户点击save按钮,我可以保存子上下文,子上下文的所有更改都将被推送到父上下文。当用户点击“取消”按钮时,我只需关闭视图控制器,所有更改都将丢失。在这里,我的所有子视图控制器都是详细信息检查器,在其中使用编辑数据,因此没有获取的结果控制器。您可以使用
[context rollback]在一个上下文中实现同样的效果
而不是
[上下文保存:nil]。如果提取细节视图控制器需要花费过多的时间,WWDC视频非常有用。我想你可能不理解我的问题。我的问题与此类似。但在我的例子中,我有多层次的子上下文。使用
[context rollback]
时,我的所有更改都将丢失。但我只希望放弃一些更改。我将上传一个样本项目很快。thanks@Mundi“你对上下文的理解完全错误。你只需要一个上下文。句号。”等等。什么?!不,不,上下文是一组更改。在您提交之前,它不会持久化。您可以,也应该,拥有尽可能多的更改集。从NSManagedObjectContext文档中的前两段应该非常清楚:在他的用例中,这正是他所需要的。这个答案是根据OP的技能和经验水平量身定制的。在所有的向下钻取中,我都有编辑任务。我刚刚设法在一些向下钻取中减少了一些保存/取消操作。使用此模型一段时间后,我发现的唯一问题是,创建的关系在父子关系中不可见。这只发生在ios 5中,这是一个已知的bug,我在保存儿童上下文之前调用了OccainPermanentids来修复它。天啊,+krishnan,在找到这条评论之前,我把头发撕了一半,并尝试添加了一个OccainPermanentids调用。
EntityA           -- ( Edit View Controller  - uses ChildContext )
 |
 |- Field1
 |
 |- Field2
 |
 |- RelationShip (1 to Many ) - ( Relationship Add / Edit View Controller - uses GrandChildContext )
     |
     |- Field1
     |    .
     |    .
     |- Field3
     |
     |- Relationship ( 1 to Many ) - ( Relationship Add / Edit View Controller - uses GrandGrandChildContext )
            |
            |- Field1
            |
            |- Field2