2016-11-29 57 views
0

我有一個NSWindowController,它顯示一個表格,並使用另一個控制器作爲數據源並委託NSTableView。第二個控制器顯示來自對象的信息,該對象由NSWindowController傳入。該控制器依次將對象設置爲AppDelegate的屬性。它看起來像這樣:傳遞永遠不會變成NSWindowController的對象的正確方法是什麼?

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中做正確的事情。

回答

0

有幾件事情:

是否有任何理由你是在代碼中創建你的窗口控制器而不是從情節提要/廈門國際銀行加載它?

通常,更好的做法是將與視圖相關的所有'控制器'放在NSViewController中,並且僅將NSWindowController用於與窗口本身相關的內容(例如工具欄,窗口管理等)。

與iOS類似,NSViewController現在已集成到窗口/視圖生命週期和響應者鏈中。對於很多窗口,您甚至不需要子類NSWindowController

XCode的應用程序項目模板使用窗口,主視圖及其控制器創建故事板。這是一個很好的起點。

NSWindowController有一個contentViewController屬性設置爲主內容視圖的NSViewController(從故事板加載時)。通常,視圖控制器不需要單獨的視圖控制器屬性。

我認爲,通常情況下,您想盡量減少從外部代碼修改您的控制器,並儘可能使它們獨立。這使得它們更具可測試性和可重用性。

如果您Thing實例是全球性的整個應用程序(因爲它從你的代碼出現),你可能要考慮將其添加爲一個單一實例的Thing類,並從NSViewController取回(例如,在viewDidLoad()

如果你把你的控制器/視圖放在故事板中,你可以在那裏連接表的數據源/委託。如果這是您的主窗口,它可以在應用程序啓動時自動加載並顯示它。但無論如何,請將您的NSViewController/View接線放在視圖控制器中。

如果要將主要NSViewController之間的邏輯分離爲處理視圖特定部分的更專用視圖控制器,則可以在Interface Builder中使用NSContainerView來添加其他視圖控制器來處理特定視圖。

+0

謝謝,你說服我看看故事板,他們肯定是前進的方向。欣賞它! –

相關問題