Core data 在使用NSDocument时,如何将情节提要视图绑定到核心数据实体?

Core data 在使用NSDocument时,如何将情节提要视图绑定到核心数据实体?,core-data,cocoa-bindings,xcode-storyboard,nsdocument,Core Data,Cocoa Bindings,Xcode Storyboard,Nsdocument,我正在构建一个使用核心数据、NSDocument、故事板和Cocoa绑定的OSX应用程序 我预计会发生以下情况: 创建了MyDocument(NSDocument子类)的实例 MyDocument创建表示文档数据的核心数据NSManagedObjectContext MyDocument根据脚本中的标识符实例化NSWindowController 在情节提要中,窗口控制器包含显示和编辑文档的DocumentEditorViewController(NSViewController子类) 在情节提

我正在构建一个使用核心数据、NSDocument、故事板和Cocoa绑定的OSX应用程序

我预计会发生以下情况:

  • 创建了
    MyDocument
    NSDocument
    子类)的实例

  • MyDocument
    创建表示文档数据的核心数据
    NSManagedObjectContext

  • MyDocument
    根据脚本中的标识符实例化
    NSWindowController

  • 在情节提要中,窗口控制器包含显示和编辑文档的
    DocumentEditorViewController
    NSViewController
    子类)

  • 在情节提要中,
    DocumentEditorViewController
    有一个绑定到
    MyDocument
    的托管对象上下文的
    NSArrayController

  • 在情节提要中,
    DocumentEditorViewController
    有一个绑定到
    NSArrayController
    的表视图

  • 这样,用户界面中的任何更改都可以直接进入
    NSManagedObjectContext
    ,而无需任何粘合代码

    我希望这是直截了当的,因为我相信我正在以预期的方式使用这些技术。但是,我无法使绑定正常工作,特别是在步骤5和6中。我发现的所有项目模板和示例项目要么不使用核心数据,要么不使用故事板,要么不使用NSDocuments

    哪些对象应该绑定到哪些对象?NSArrayController的类、键和键路径应该是什么


    回答此问题的另一种方法是指出一个同时使用所有这些技术的工作示例项目。

    创建一个基于Xcode文档的示例应用程序项目的步骤,包括核心数据、故事板、NSArrayController、NSTableView和绑定

    步骤1创建一个Xcode项目。选择OS X Cocoa应用程序并选择“使用故事板”、“创建基于文档的应用程序”和“使用核心数据”

    步骤2选择数据模型。添加实体“Person”和字符串属性“name”和“address”

    步骤3选择Main.storyboard。将NSArrayController添加到视图控制器场景。将模式设置为“实体名称”,并将实体名称设置为“人员”。选中“准备内容”。将阵列控制器的
    托管对象上下文
    绑定到
    视图控制器
    ,模型键路径
    representedObject.managedObjectContext

    步骤4转到视图控制器场景的视图。删除“此处的文档内容”。添加一个NSTableView。将
    内容
    绑定到
    阵列控制器
    ,控制器键
    阵列对象
    。将
    选择索引
    绑定到
    阵列控制器
    ,控制器键
    选择索引
    。将
    排序描述符
    绑定到
    阵列控制器
    ,控制器键
    排序描述符

    步骤5将表视图中文本字段的
    绑定到
    表单元格视图
    、模型键路径
    objectValue.name
    objectValue.address
    。选中“条件设置可编辑”

    步骤6将两个按钮“添加”和“删除”添加到视图控制器场景的视图中。将操作连接到阵列控制器的操作
    添加:
    删除:

    步骤7(目标-C)选择Document.h。在方法
    makeWindowController
    中,将语句
    [self addWindowController:…
    替换为

    NSWindowController *aWindowController = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"Document Window Controller"];
    [self addWindowController:aWindowController];
    aWindowController.contentViewController.representedObject = aWindowController.document;
    
    步骤7(Swift)在方法
    MakeWindowController
    中选择Document.Swift.,在
    self.addWindowController(windowController)
    add之后的末尾

     windowController.contentViewController!.representedObject = windowController.document
    

    步骤8构建、运行、测试。

    您为每个文档使用单独的
    NSManagedObjectContext
    ?这是OSX/基于文档的应用程序中的推荐方式吗?在(非基于文档的)iOS应用程序中,我通常使用单个上下文(由应用程序代表拥有),以及每个模型对象的
    NSManagedObject
    的单独实例……我看不到苹果公司提供的任何示例或指南能够回答您的问题。我认为单独的托管对象上下文更有意义,因为文档是完全独立的。我认为将它们的数据混合到单个上下文中,然后将它们放在一起是没有意义的正在为当前视图的数据子集筛选对上下文的所有访问。您是否尝试过通过编程方式添加一些MOC对象并看到表视图显示这些对象的测试用例?如果您尝试调试绑定而不使用AC创建内容的能力,则在引用5和6时不清楚。@BobWhiteman您需要C绑定到上下文并获取一个特定类型的实体…如果你是智者,你可以截图AC的IB配置。它可能是安慰剂,但product->clean?可能是重复的。我正要用你刚才发布的内容回答我自己的问题。我的代码中有两个主要错误。一个是无关的,但另一个是新项目模板有问题。它会覆盖representedObject属性的didSet方法,而不实现KVC。如果设置windowController.contentViewController!。representedObject,它可以正常工作,但如果将contentViewController强制转换为window控制器子类的类型,它会破坏KVO并获得“如果没有托管对象上下文,则无法执行操作“错误。在步骤4中,在没有绑定选择索引或排序描述符的情况下,这似乎对我有效。您能描述一下为什么需要这些吗?通过绑定选择索引和排序描述符,阵列控制器和表视图的选择和排序是同步的。阵列控制器的”“选择插入的对象”“。”