本文和大家分享的主要是swift4
中KVC
和
KVO相关内容,一起来看看吧,希望对大家
学习swift有所帮助。
随着 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
实例,需要自己控制这个实例的生命周期
来源:
稀土掘金