在文字的開頭,先說一個小細節,swift中聲明一個類,你能夠集成自NSObject,也能夠選擇忽略,兩者有什麼區別呢。根據本身的經驗,我得出如下結論。不足之處,請指出。exmple:咱們聲明這樣一個類swift
class Person: NSObject {
var name: String?
override init() {
super.init()
}
}
此類打印出的內存地址是0x00000fbd00007ffeefbfc240
複製代碼
這段代碼是不會報錯的,是一個典型的swift遺留ObjC語法的寫法,可是若是咱們去掉NSObject並打印出他的內存地址,以下數組
class Person {
var name: String?
init() {
}
}
此類打印出的內存地址是0x00007ffeefbfc240
複製代碼
區別還有不少,平時在開發中你們能夠多注意這一區別。我的偏向不繼承NSObject,尤爲是我須要此類作一些騷操做時,好比KVO。bash
KVO是OC一個對象屬性的特性,因爲是面向字符串,因此開發時須要尤爲當心,這種奔潰只有執行到了纔會報錯。 聲明以下類:ide
class Person: NSObject {
@objc var age: Int?
var name: String?
var observation: NSKeyValueObservation?
override init() {
super.init()
self.observation = observe(\Person.age, options: .new, changeHandler: { (person, change) in
print("Person.age的新值 = ", change.newValue as Any)
})
}
}
複製代碼
在外部咱們,初始化一個對象,並對age進行賦值,以下ui
let person = Person()
person.age = 18
person.setValue(100, forKey: "age")
複製代碼
程序執行後,(ÒωÓױ)!爲何只有一個打印?按理說是應該打印Person.age的新值 = 18
和Person.age的新值 = 100
的呀,然而並無😆。問題出在哪,原來,swift中若是須要對一個值進行監聽,那麼必定要記住2個關鍵詞spa
不然,指針
沒有@objc程序在監聽時會觸發奔潰;code
沒有dynamic則屬性的set方法不會生效,天然就沒有上面的打印,由於KVO的本質就是監聽屬性的set方法,而可變數組的增刪操做都不會生效;對象
可是爲何KVC的操做卻能生效呢? 這是由於KVC內部的實現過程是繼承
因此正確的寫法應該是
class Person: NSObject {
@objc dynamic var age: Int?
var name: String?
var observation: NSKeyValueObservation?
override init() {
super.init()
self.observation = observe(\Person.age, options: .new, changeHandler: { (person, change) in
print("Person.age的新值 = ", change.newValue as Any)
})
}
}
複製代碼