【问题标题】:How to use NSObjectController and Managed Object Context using Cocoa Bindings如何使用 NSObjectController 和使用 Cocoa 绑定的托管对象上下文
【发布时间】:2018-06-20 05:10:49
【问题描述】:

搜索了整个互联网,但找不到我的问题的现代解决方案。 我想通过 Cocoa Bindings 将 NSObjectController 与 Core Data 配对使用,并努力正确设置它。值得注意的是,我使用的是最新版本的 Xcode 和 Swift。

我做了什么:

出于测试目的,我做了以下操作:

  1. 创建了一个选择“使用核心数据”选项的 macOS 应用程序(该应用程序基于文档);
  2. 将 2 个 NSTextField 拖入 Storyboard 将 NSObjectController 拖入视图控制器场景;
  3. 为核心数据模型添加了员工实体,具有 2 个属性“姓名”和“姓氏”;
  4. How do I bind my Array Controller to my core data model? 的答案中完成所有操作
  5. 将 NSObjectController 设置为实体模式并输入“Employee”,
  6. 选择准备内容,选择使用延迟获取,因此选中所有三个选项;
  7. 在绑定检查器中将 NSObjectController 的 Managed Object Context 绑定到 View Controller 的 managedObjectContext;
  8. 绑定的 NSTextFields 如下:Value - 对象控制器,控制器键 - 选择,模型键路径 - 名称(用于第一个文本字段)和姓氏(第二个)。

就是这样。

第一组问题:我做错了什么以及如果不是完全错误的方法如何解决?

我在 stackoverflow 上的一些帖子中读到,这样做可以自动保存和从 Core Data 模型中获取。这就是为什么我认为它应该可以工作。

所以这是第二组问题: 这是真的吗? 如果是,那么为什么在显示视图时不填充文本字段? 如果不是,那么如果可能的话如何实现(尽量少写代码)?

第三个问题:如果我使用了完全错误的方法,是否有人可以帮助我使用 Cocoa 绑定来连接 Core Data 和 NSObjectController,并向我展示使用尽可能少的代码编写的方法正确的方法?

考虑到目前还没有关于这个主题的新帖子,我认为正确的答案可以帮助很多正在开发 macOS 应用程序的人。

提前致谢!

【问题讨论】:

  • 您得到了什么结果,它们与您的预期有何不同?
  • Textfileds 没有填满我输入的数据。我假设这些字段的数据会在我退出应用程序时自动保存,并在视图控制器加载时从数据模型中获取并显示在文本字段中。
  • 您没有提到任何有关插入 Employee 对象的内容。我的意思是,当你第一次启动这个应用程序时,对象图(在用户商店中)是空的,你的文本字段可能会显示“没有选择”。您需要一些代码来执行对 Employee 对象的提取,如果没有找到(第一次启动时会发生)插入一个。你可以把这样的代码放在applicationDidFinishLaunching
  • 文本字段确实显示没有选择!我是否需要为此从实体创建 NSManagedObject 子类,还是有其他解决方案?在 applicationDidFinishLaunching 中应该使用什么代码来插入对象?我想我最初的方法是半正确的?对吗??????
  • 你能发布一个链接到“stackoverflow 上的帖子就是这样做的”吗?

标签: macos core-data nsmanagedobjectcontext cocoa-bindings nsobjectcontroller


【解决方案1】:

我认为您的基本方法是正确的,尽管重要的是要了解您需要一个真实的对象,一个实例,以便它工作。

创建 NSManagedObject 子类通常是可取的,并且几乎总是在实际项目中完成,因此您可以定义和使用属性。现在,您可以通过在 Xcode 的 Project Navigator 中选择数据模型并单击菜单轻松完成此操作:Editor > Create NSManagedObject Subclass...。从技术上讲,这不是必需的,并且在演示或概念验证中,您经常会使用 NSManagedObject。

假设您正在使用您所描述的 Xcode 项目模板,其中 AppDelegate 具有属性 managedObjectContext,您的 AppDelegate 类中的以下函数将维护、在必要时创建并返回,我称之为 单一对象 – 特定实体的对象,在本例中为 Employee,您的应用要求商店中只有一个对象。

@discardableResult func singularEmployee() -> NSManagedObject? {
    var singularEmployee: NSManagedObject? = nil
    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "Employee")
    let objects = try? self.managedObjectContext.fetch(fetchRequest)
    singularEmployee = objects?.first

    if singularEmployee == nil {
        singularEmployee = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: self.managedObjectContext)
    }
    return singularEmployee
}

然后,将这行代码添加到applicationDidFinishLaunching

    singularEmployee()

【讨论】:

  • 谢谢杰瑞!您简化了实体的第一个真实对象的创建!所以唯一剩下的就是添加@objc let managedObjectContext 到视图控制器,将其绑定到 NSObjectControlller 并将这些文本字段绑定到对象控制器(实体属性)。同时,我阅读了 Marcus Zarra 关于核心数据的书并了解到,将 NSObjectController 和 Core Data 一起使用会自动从核心数据模型中检索数据,删除和更新值,但是为了保存 managedObjectContext 你需要显式调用 managedObjectContext.save ()。所以没有自动保存,很遗憾。
  • 我认为 Apple 认为 没有自动保存 是一项功能,而不是错误。托管对象上下文被认为是您的“便签本”。有许多函数可能适合 save() 它。这里有四个:(1)文本字段的endEditing(),(2)参数为nil时superview的viewWillMove(toWindow:),(3)窗口的windowWillClose(),(4)NSApp的applicationWillTerminate()。跨度>
猜你喜欢
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多