传递一个永远不会改变为NSWindowController的对象的正确方法是什么?

时间:2016-11-29 23:29:04

标签: swift nswindowcontroller

我有一个显示表的NSWindowController,并使用另一个控制器作为NSTableView的数据源和委托。第二个控制器显示来自对象的信息,该信息由NSWindowController传入。该控制器依次将对象设置为AppDelegate的属性。它看起来像这样:

class SomeWindowController: NSWindowController {
    var relevantThing: Thing!
    var someTableController: SomeTableController!
    @IBOutlet weak var someTable: NSTableView!

    override func windowDidLoad() {
        someTableController = SomeTableController(thing: relevantThing)
        someTable.dataSource = someTableController
        someTable.delegate = someTableController
    }
}

AppDelegate我然后做

之类的事情
func applicationDidFinishLaunching(_ aNotification: Notification) {
    relevantThing = Thing()
    someWindowController = SomeWindowController()
    someWindowController.relevantThing = relevantThing
    someWindowController.showWindow(nil)
}

这是一种合理的方法吗?我觉得SomeWindowController中使用的隐式解包选项可能是不好的形式。此外,relevantThing不允许在我的情况下更改,因此我觉得let会更正确。也许relevantThing应该保持不变并通过初始化器传入?或者会破坏init?(coder: NSCoder)初始化程序?

我非常感谢任何建议,因为我试图了解在Swift中做正确事情的正确方法。

1 个答案:

答案 0 :(得分:0)

一些事情:

您是否有任何理由在代码中创建窗口控制器而不是从storyboard / xib加载它?

通常,更好的做法是将所有“控制器”放在一起。这与NSViewController中的视图相关,仅使用NSWindowController与窗口本身相关的内容(例如工具栏,窗口管理等)。

与iOS类似,NSViewController现已集成到窗口/视图生命周期和响应程序链中。对于许多窗口,您甚至不需要继承NSWindowController

XCode的应用程序项目模板使用窗口,主视图及其控制器创建故事板。这是一个很好的起点。

NSWindowController具有contentViewController属性,该属性设置为主内容视图的NSViewController(从故事板加载时)。您通常不需要视图控制器的单独视图控制器属性。

我认为通常,您希望最大限度地减少从外部代码修改控制器并使其尽可能独立。这使它们更易于测试和重复使用。

如果您的Thing实例对于整个应用程序是全局的(从代码中显示),您可能需要考虑将其作为单例实例添加到Thing类并从中检索它NSViewController(例如在viewDidLoad()

如果您将控制器/视图放在故事板中,则可以在此处连接表的数据源/委托。如果这是您的主窗口,它可以加载并在应用程序启动时自动显示。但无论如何,请将NSViewController / View布线放在视图控制器中。

如果要将主NSViewController之间的逻辑分离为处理视图特定部分的更专业的视图控制器,可以在Interface Builder中使用NSContainerView添加其他视图控制器来处理特定视图。 / p>