在应用程序启动时将对象传递给NSViewController的最佳方法是什么?

时间:2016-12-02 00:30:54

标签: swift cocoa

在我的AppDelegate applicationDidFinishLaunching中,我需要使用从磁盘读取的数据创建对象,然后将此对象传递给初始视图控制器以进行显示。最好的方法是什么?

现在我正在以编程方式加载故事板:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    importantThing = ImportantThing()
    importantThing.load(url: URL(fileURLWithPath: "..."))

    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    myWindowController = storyboard.instantiateController(withIdentifier: "MyWindowController") as! NSWindowController
    (myWindowController.contentViewController as? MyViewController)?.importantThing = importantThing
    myWindowController.showWindow(self)
}

但这感觉很笨拙。首先,该属性是在viewDidLoad之后设置的,所以现在查看设置很奇怪。

必须有更好的方法来做到这一点。如果可能的话,我不想使用单例,因为我实际上需要设置一些互连的对象(两个具有重要状态的对象相互引用,但是对于包含它们的任何一个都没有意义其他)。什么是解决这个问题的好方法?

1 个答案:

答案 0 :(得分:1)

您在应用代理中所做的是正确的。至于你应该在视图控制器中做什么,Apple的Master-Detail app模板会显示正确的模式(我添加了一些注释):

// the interface
@IBOutlet weak var detailDescriptionLabel: UILabel!

// the property
var detailItem: NSDate? {
    didSet {
        self.configureView()
    }
}

func configureView() {
    // check _both_ the property _and_ the interface
    if let detail = self.detailItem { // property set?
        if let label = self.detailDescriptionLabel { // interface exists?
            label.text = detail.description
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    // at this point, its _certain_ that the interface exists
    self.configureView()
}

如果您考虑一下,您将看到界面正确更新,无论事件的顺序如何 - 即,无论viewDidLoad还是属性的设置先到了。按照这种模式。