本文和大家分享的主要是swift4
中KVC
和
KVO相關(guān)內(nèi)容,一起來(lái)看看吧,希望對(duì)大家
學(xué)習(xí)swift有所幫助。
隨著 keypath
得到增強(qiáng),
KVC
和
KVO
的
API
都有了一些進(jìn)化。
struct 也支持 KVC
一個(gè)感人的進(jìn)步就是 struct
也支持
KVC
了。但是并不是使用原有的
setValue:forKeypath
的api
。而是利用了
swfit 4
增加的一個(gè)語(yǔ)法特性:自定義索引可以有參數(shù)名。
直接上代碼吧:
struct ValueType {
var name:String
}
var
object = ValueType(name: "zhuo")
let name = \ValueType.name
// set
object[keyPath: name] = "swift4"http:// get
let valueOfName =
object[keyPath:name]
通過(guò)索引可以方便的進(jìn)行KVC
。
KVO
遺憾的是依然只有 NSObject
才能支持
KVO
。
Swift 4
中的一個(gè)對(duì)此有影響的改變是繼承
NSObject
的
swift class
不再默認(rèn)全部
bridge
到
OC
。原因可以參考我的前一篇博客:
Swift 4新知:自動(dòng)清除冗余代碼減小包大小
。然而 KVO
又是一個(gè)純
OC
的特性,所以如果是
swift class
需要在聲明的時(shí)候增加
@objcMembers
關(guān)鍵字。否則在運(yùn)行的時(shí)候你會(huì)得到一個(gè) error
:
fatal error: Could not extract a String from KeyPath Swift.ReferenceWritableKeyPath
另外一件事就是被觀察的屬性
需要用 dynamic 修飾
,否則也無(wú)法觀察到。
一個(gè)好消息是不需要在對(duì)象被回收時(shí)手動(dòng) remove observer
。但是這也帶來(lái)了另外一個(gè)容易被忽略的事情:觀察的閉包沒(méi)有被強(qiáng)引用,需要我們自己添加引用,否則當(dāng)前函數(shù)離開(kāi)后這個(gè)觀察閉包就會(huì)被回收了。
@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
之后返回的是一個(gè)
NSKeyValueObservation
實(shí)例,需要自己控制這個(gè)實(shí)例的生命周期
來(lái)源:
稀土掘金