OS X核心数据 - 将托管对象上下文传递给视图控制器

时间:2016-06-13 12:12:45

标签: macos core-data cocoa-bindings

我正在Xcode 7.3.1中开发Mac应用程序。我试图将模型对象上下文从我的AppDelegate传递给ArrayController。

我有一个名为DataController的类,它创建了我的核心数据堆栈。 DataController.managedObjectContext保存托管对象上下文。

我的AppDelegate类如下:

class AppDelegate: NSObject, NSApplicationDelegate {

  var dataController: DataController!

  func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application

    // Create an instance of the DataController class.
    dataController = DataController()

    // Create a reference to the first ViewController embedded in the WindowController.
    guard let splitViewController = NSApplication.sharedApplication().windows[0].contentViewController as? ManagedObjectContextSettable
        else { fatalError("Wrong view controller type")}

    // Set the managedObjectContext property.
    splitViewController.managedObjectContext = dataController.managedObjectContext
  }

  func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
  }

}

在我的故事板中,我在WindowController中嵌入了一个SplitViewController。 SplitViewController有自己的自定义View Controller类,名为SplitViewController。这是SplitViewController中的代码:

class SplitViewController: NSSplitViewController, ManagedObjectContextSettable {

  var managedObjectContext: NSManagedObjectContext!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.


    // Create a reference to the first ViewController embedded in the WindowController.
    let childControllers = self.childViewControllers

    print("childControllers.count = \(childControllers.count)")

    for childController in childControllers{

        if childController.isKindOfClass(TableViewController){

            print("Found TableViewController")

            guard let tableViewController = childController as? ManagedObjectContextSettable
                else { fatalError("Wrong view controller type")}

            tableViewController.managedObjectContext = managedObjectContext

        }
    }
  }
}

其中一个拆分视图项是我的TableView,它有自己的名为TableViewController的视图控制器。这是TableViewController的代码:

class TableViewController: NSViewController, ManagedObjectContextSettable, NSTableViewDataSource, NSTableViewDelegate {

  @IBOutlet weak var tableView: NSTableView!

  var managedObjectContext: NSManagedObjectContext!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.
    //print(managedObjectContext.description)
  }

}

在故事板中,我拖动了一个ArrayController,在Inspector的Bindings选项卡中,我设置了Bind To并选择了TableViewController,并将Model Key Path设置为'self.managedObjectContext'。最终它没有收到托管对象上下文。

我无法确定是否应该覆盖嵌入式ViewController的prepareForSegue函数,我读到的每个示例都是针对IOS的。

我哪里出错了?

3 个答案:

答案 0 :(得分:0)

applicationDidFinishLaunching可以在viewDidLoad之后执行。设置splitViewController的managedObjectContext时设置childControllers的managedObjectContext

绑定使用KVO。将var managedObjectContext更改为dynamic var managedObjectContext以使属性符合KVO。

答案 1 :(得分:0)

如果您正在使用带有Cocoa绑定的数组控制器,则必须覆盖init(coder:)方法并初始化托管上下文以执行隐式初始提取。 viewDidLoad为时已晚。

segue工作流程与iOS相同。它更方便,因为有一个属性presentingViewController来获取对父视图控制器的引用。

核心数据管理器DataController应该是一个单例,以确保托管对象上下文实例始终相同。

答案 2 :(得分:0)

这可能不是一个好习惯,但似乎有效。

我使我的DataController类成为单例类,以确保只有一个托管对象上下文。在我的TableViewController中,我创建了一个managedObjectContext属性,如下所示:

    lazy var managedObjectContext = DataController.sharedInstance.managedObjectContext

在我的数组控制器中,我将托管对象上下文参数绑定到TableViewController,并将模型密钥路径设置为self.managedObjectContext。

可以改进吗?