在我的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
之后设置的,所以现在查看设置很奇怪。
必须有更好的方法来做到这一点。如果可能的话,我不想使用单例,因为我实际上需要设置一些互连的对象(两个具有重要状态的对象相互引用,但是对于包含它们的任何一个都没有意义其他)。什么是解决这个问题的好方法?
答案 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
还是属性的设置先到了。按照这种模式。