- 多窗口
macOS 支持多窗口, 但是如果創(chuàng)建出來的 window 沒有對(duì)象被持有的話, window 對(duì)象就會(huì)被清除, 后果就是 window 自動(dòng)就被關(guān)閉了.
比如這一段代碼:
錯(cuò)誤示例
func somemethod() {
let window = NSStoryboard(name: "someStoryBoard", bundle: nil).instantiateInitialController() as? NSWindowController
window?.showWindow(nil)
}
你運(yùn)行之后可能根本看不到彈出的窗口.坑啊.
正確示例
...
class SomeClass {
...
lazy var window = NSStoryboard(name: "someStoryBoard", bundle: nil).instantiateInitialController() as? NSWindowController
...
func somemethod() {
self.window?.showWindow(nil)
}
...
}
- Swift 的值綁定
正常情況下, 你如果用swift 來進(jìn)行值綁定, 你可能只能看到單向的更新, 即界面上的內(nèi)容改變, 如文本框修改了文字, 你可以看到你綁定的值發(fā)生變化.如下所示
class ViewController: NSViewController {
var value:String = "" {
didSet {
print("new value", self.value)
}
}
}

設(shè)置的值綁定. PS: 勾上 Continuously Updates Value 能夠即時(shí)修改綁定值
運(yùn)行效果

可以看到, 值發(fā)生了變化
如果你直接修改值, 按理說界面上也會(huì)發(fā)生變化才對(duì), 實(shí)際呢?
例如我們?cè)诎粹o的事件中將值變成大寫字母
...
@IBAction func upperClick(_ sender: Any) {
self.value = self.value.uppercased()
}
...

值發(fā)生了變化, 界面卻還是一樣的
那正確的方法是如何呢?
在綁定值前加一個(gè) dynamic 就行了
dynamic var value:String = "" {
didSet {
print("new value", self.value)
}
}

搞定
為何會(huì)這樣?
這個(gè)問題, 分成兩個(gè)方面來看. 熟悉 iOS, macOS 開發(fā)的同學(xué)都知道, kvo, kvc.
由界面到值更新過程是 kvc的, swift 中, 只要是繼承自 NSObject 的類都可以使用 kvc. ViewController 自然是繼承自 NSObject. 所以普通的單向更新沒有問題.
由值到界面上的更新過程是 kvo 實(shí)現(xiàn)的. swift 中的 kvo , 除了要求類本身是繼承自 NSObject 之外, 還需要值標(biāo)記為 dynamic. 可以參考swifter 的這篇文章