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<iOS11.XXX, Swift.String>  

另外一件事就是被观察的属性需要用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 实例,需要自己控制这个实例的生命周期。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值