Swift 4新知:KVC和KVO新姿势

原文

随着 keypath 得到增强,KVC 和 KVO 的 API 都有了一些进化。

struct 也支持 KVC

一个感人的进步就是 struct 也支持 KVC 了。但是并不是使用原有的setValue:forKeypath的api。而是利用了swfit 4增加的一个语法特性:自定义索引可以有参数名。

直接上代码吧:

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。

KVO

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

Swift 4中的一个对此有影响的改变是继承 NSObject 的 swift class 不再默认全部 bridge 到 OC。原因可以参考我的前一篇博客Swift 4新知:自动清除冗余代码减小包大小。然而 KVO 又是一个纯 OC 的特性,所以如果是 swift class 需要在声明的时候增加 @objcMembers 关键字。否则在运行的时候你会得到一个 error:

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

另外一件事就是被观察的属性需要用dynamic修饰,否则也无法观察到。

一个好消息是不需要在对象被回收时手动 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 实例,需要自己控制这个实例的生命周期。

参考:

Key Value Observation in iOS 11

smart key path

Re-enabling @objc inference within a class hierarchy

欢迎关注我的微博@没故事的卓同学

Swift 4新知:KVC和KVO新姿势

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Swift 4新知:KVC和KVO新姿势

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址