macOS 开发遇到的坑

  1. 多窗口
    macOS 支持多窗口, 但是如果创建出来的 window 没有对象被持有的话, window 对象就会被清除, 后果就是 window 自动就被关闭了.
    比如这一段代码:
    错误示例
   func somemethod() {
       let window = NSStoryboard(name: "someStoryBoard", bundle: nil).instantiateInitialController() as? NSWindowController
       window?.showWindow(nil)
   }

你运行之后可能根本看不到弹出的窗口.坑啊.
正确示例

...
class SomeClass {
...
lazy var window = NSStoryboard(name: "someStoryBoard", bundle: nil).instantiateInitialController() as? NSWindowController
...
   func somemethod() {
       self.window?.showWindow(nil)
   }
...
}
  1. Swift 的值绑定
    正常情况下, 你如果用swift 来进行值绑定, 你可能只能看到单向的更新, 即界面上的内容改变, 如文本框修改了文字, 你可以看到你绑定的值发生变化.如下所示
class ViewController: NSViewController {
    var value:String = "" {
        didSet {
            print("new value", self.value)
        }
    }
}
macOS 开发遇到的坑_第1张图片
设置的值绑定. PS: 勾上 Continuously Updates Value 能够即时修改绑定值

运行效果

macOS 开发遇到的坑_第2张图片
可以看到, 值发生了变化

如果你直接修改值, 按理说界面上也会发生变化才对, 实际呢?
例如我们在按钮的事件中将值变成大写字母

...
@IBAction func upperClick(_ sender: Any) {
    self.value = self.value.uppercased()
}
...
macOS 开发遇到的坑_第3张图片
值发生了变化, 界面却还是一样的

那正确的方法是如何呢?
在绑定值前加一个 dynamic 就行了

dynamic var value:String = "" {
    didSet {
        print("new value", self.value)
    }
}

macOS 开发遇到的坑_第4张图片
搞定

为何会这样?
这个问题, 分成两个方面来看. 熟悉 iOS, macOS 开发的同学都知道, kvo, kvc.
由界面到值更新过程是 kvc的, swift 中, 只要是继承自 NSObject 的类都可以使用 kvc. ViewController 自然是继承自 NSObject. 所以普通的单向更新没有问题.
由值到界面上的更新过程是 kvo 实现的. swift 中的 kvo , 除了要求类本身是继承自 NSObject 之外, 还需要值标记为 dynamic. 可以参考 swifter 的这篇文章

你可能感兴趣的:(macOS 开发遇到的坑)