2016-06-13 5 views
0

Xcode 7.3.1でMacアプリケーションを開発しています。モデルオブジェクトコンテキストをAppDelegateからArrayControllerに渡そうとしています。OS Xのコアデータ - 管理されたオブジェクトコンテキストをView Controllerに渡す

私は、私のコアデータスタックを作成する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には、SplitViewControllerという独自のカスタムView Controllerクラスがあります。ここでは、コードSplitViewControllerである:分割表示項目の1つに

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 

     } 
    } 
    } 
} 

は、独自のビューコントローラが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をドラッグしてインスペクタのバインド]タブで、私はバインドするために設定してTableViewControllerを選択し、「self.managedObjectContext」へのモデルのキーのパスを設定しています。最終的には、マネージドオブジェクトコンテキストを受け取っていません。

組み込みViewControllerのprepareForSegue関数をオーバーライドする必要があるかどうかを確認することはできません。

どこが間違っていますか?

答えて

0

applicationDidFinishLaunchingviewDidLoadの後に実行できます。 splitViewControllerのmanagedObjectContextが設定されている場合、子コントロールのmanagedObjectContextを設定します。

バインディングはKVOを使用します。 var managedObjectContextdynamic var managedObjectContextに変更して、プロパティKVOに準拠させます。

+0

私は、AppControllerのviewDidLoadメソッドのすべての後にAppDelegate.applicationDidFinishLoadingが実行されていることに気付きました。 AppDelegate.applicationDidFinishLoadingメソッドでSplitViewControllerの子ビューコントローラ(TableViewController)のmanagedObjectContext変数を設定することをお勧めしますか? – TDC

+0

私は 'SplitViewController'の' viewDidLoad'が 'TableViewController'の' viewDidLoad'の前に実行できることを提案しています。 'managedObjectContext'のセッターを実装し、childControllersに伝播します。 – Willeke

+0

もう一つの考えられる解決策は、arraycontrollerの 'managedObjectContext'をプログラム的に' dataController.managedObjectContext'にバインドすることです。 (私はストーリーボードやビューコントローラの開発者がバインディングについて聞いたことはないと思う) – Willeke

0

Cocoaバインディングでアレイコントローラを使用している場合は、init(coder:)メソッドをオーバーライドし、管理コンテキストを初期化して暗黙の初期フェッチを実行する必要があります。 viewDidLoadが遅すぎます。

segueワークフローはiOSと同じです。親ビューコントローラへの参照を取得するためのプロパティがpresentingViewControllerであるため、さらに便利です。

コアデータマネージャーDataControllerは、管理オブジェクトコンテキストのインスタンスが常に同じであることを保証するためのシングルトンとされています。

+0

非常に役に立ちました。私はAppDelegateのinitをオーバーライドしてMOCをSplitViewControllerに渡し、SplitViewControllerのprepareForSegueをオーバーライドしてMOCをTableViewControllerに渡しますか? – TDC

+0

AppDelegateではなく、アレイコントローラとバインディングを使用するコントローラでのみ使用できます。シングルトンを使用する場合は、AppDelegateでスタックを初期化し、シングルトンからコンテキストを取得します。 – vadian

+0

私は自分のDataControllerクラスのインスタンスを、ArrayControllerがあるコントローラ内に直接作成します。では、AppDelegateのMOCをWindowの子ビューコントローラに渡し、子から子へとMOCを渡すことをAppleが提案するのはなぜですか? – TDC

0

これは良い方法ではないかもしれませんが、うまくいくようです。

DataControllerクラスをシングルトンクラスにして、マネージオブジェクトコンテキストが1つしかないことを確認しました。

lazy var managedObjectContext = DataController.sharedInstance.managedObjectContext 

を私のアレイコントローラでは、私はTableViewControllerに管理オブジェクトコンテキストパラメータをバインドし、self.managedObjectContextにモデルのキーのパスを設定して次のように私のTableViewControllerでは、私はmanagedObjectContextプロパティを作成しました。

これを改善できますか?

関連する問題