Swift 4新知:KVC和KVO新姿式

随着 keypath 获得加强,KVC 和 KVO 的 API 都有了一些进化。html

struct 也支持 KVC

一个感人的进步就是 struct 也支持 KVC 了。可是并非使用原有的setValue:forKeypath的api。而是利用了swfit 4增长的一个语法特性:自定义索引能够有参数名。
直接上代码吧:ios

struct ValueType {
    var name:String
}

var object = ValueType(name: "zhuo")
let name = \ValueType.name

// set
object[keyPath: name] = "swift4"
// get
let valueOfName = object[keyPath:name]复制代码

经过索引能够方便的进行KVC。git

KVO

遗憾的是依然只有 NSObject 才能支持 KVO。github

Swift 4中的一个对此有影响的改变是继承 NSObject 的 swift class 再也不默认所有 bridge 到 OC。缘由能够参考个人前一篇博客:Swift 4新知:自动清除冗余代码减少包大小。然而 KVO 又是一个纯 OC 的特性,因此若是是 swift class 须要在声明的时候增长 @objcMembers 关键字。不然在运行的时候你会获得一个 error:web

fatal error: Could not extract a String from KeyPath Swift.ReferenceWritableKeyPath swift

另一件事就是被观察的属性须要用dynamic修饰,不然也没法观察到。api

一个好消息是不须要在对象被回收时手动 remove observer。可是这也带来了另一个容易被忽略的事情:观察的闭包没有被强引用,须要咱们本身添加引用,不然当前函数离开后这个观察闭包就会被回收了。闭包

@objcMembers class OCClass: NSObject {
    dynamic var name: String

    init(name: String) {
        self.name = name
    }
}

class ViewController: UIViewController {

    var swiftClass: OCClass!
    var ob: NSKeyValueObservation!

    override func viewDidLoad() {
        super.viewDidLoad()

        swiftClass = OCClass(name: "oc")
        ob = swiftClass.observe(\.name) { (ob, changed) in
            let new = ob.name
            print(new)
        }
        swiftClass.name = "swift4"
    }
}复制代码

KVO 以后返回的是一个 NSKeyValueObservation 实例,须要本身控制这个实例的生命周期。app

参考:
Key Value Observation in iOS 11
smart key path
Re-enabling @objc inference within a class hierarchyide

欢迎关注个人微博:@没故事的卓同窗

相关文章
相关标签/搜索