亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

在Swift中使用KVO的細節(jié)以及內(nèi)部實現(xiàn)解析(推薦)

 更新時間:2020年07月21日 10:00:34   作者:雨人在掘金  
這篇文章主要介紹了在Swift中使用KVO的細節(jié)以及內(nèi)部實現(xiàn)解析,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

KVO是什么?

KVO 是 Objective-C 對觀察者設(shè)計模式的一種實現(xiàn)?!玖硗庖环N是:通知機制(notification),詳情參考:iOS 趣談設(shè)計模式——通知】;
KVO提供一種機制,指定一個被觀察對象(例如A類),當對象某個屬性(例如A中的字符串name)發(fā)生更改時,對象會獲得通知,并作出相應(yīng)處理;【且不需要給被觀察的對象添加任何額外代碼,就能使用KVO機制】
在MVC設(shè)計架構(gòu)下的項目,KVO機制很適合實現(xiàn)mode模型和view視圖之間的通訊。

例如:代碼中,在模型類A創(chuàng)建屬性數(shù)據(jù),在控制器中創(chuàng)建觀察者,一旦屬性數(shù)據(jù)發(fā)生改變就收到觀察者收到通知,通過KVO再在控制器使用回調(diào)方法處理實現(xiàn)視圖B的更新;(本文中的應(yīng)用就是這樣的例子.)

實現(xiàn)原理?

KVO在Apple中的API文檔如下:

Automatic key-value observing is implemented using a technique called isa-swizzling… When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class …
KVO 的實現(xiàn)依賴于 Objective-C 強大的 Runtime【可參考:Runtime的幾個小例子】 ,從以上Apple 的文檔可以看出蘋果對于KVO機制的實現(xiàn)是一筆帶過,而具體的細節(jié)沒有過多的描述,但是我們可以通過Runtime的所提供的方法去探索,關(guān)于KVO機制的底層實現(xiàn)原理。為此啊左從網(wǎng)上的一些關(guān)于KVO的資料總結(jié)了有關(guān)的內(nèi)容:

基本的原理:

當觀察某對象A時,KVO機制動態(tài)創(chuàng)建一個對象A當前類的子類,并為這個新的子類重寫了被觀察屬性keyPath的setter 方法。setter 方法隨后負責(zé)通知觀察對象屬性的改變狀況。

好了,下面本文重點內(nèi)容:

在文字的開頭,先說一個小細節(jié),swift中聲明一個類,你可以集成自NSObject,也可以選擇忽略,二者有什么區(qū)別呢。根據(jù)自己的經(jīng)驗,我得出以下結(jié)論。不足之處,請指出。exmple:我們聲明這樣一個類

class Person: NSObject {
 var name: String?
 override init() {
  super.init()
 }
}
此類打印出的內(nèi)存地址是0x00000fbd00007ffeefbfc240

這段代碼是不會報錯的,是一個典型的swift遺留ObjC語法的寫法,但是如果我們?nèi)サ鬘SObject并打印出他的內(nèi)存地址,如下

class Person {
 var name: String?
 init() {
  
 }
}
此類打印出的內(nèi)存地址是0x00007ffeefbfc240
  • 內(nèi)存地址不一樣,繼承自NSObject的類對象的內(nèi)存地址明顯長度多了8個長度,why?多出的8個空間就是為了存放ObjC對象內(nèi)的isa指針,有興趣的可以往下研究。
  • 繼承自NSObject的類可以使用OC里的一些騷操作,比如KVC、KVO、runtime,否則使用setValue-forKey時是會報錯的。

區(qū)別還有很多,平時在開發(fā)中大家可以多注意這一區(qū)別。個人偏向不繼承NSObject,尤其是我需要此類做一些騷操作時,比如KVO。

KVO是OC一個對象屬性的特性,由于是面向字符串,所以開發(fā)時需要尤其小心,這種奔潰只有執(zhí)行到了才會報錯。聲明如下類:

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進行賦值,如下

let person = Person()
person.age = 18
person.setValue(100, forKey: "age")

程序執(zhí)行后,(ÒωÓױ)!為什么只有一個打???按理說是應(yīng)該打印Person.age的新值 = 18Person.age的新值 = 100的呀,然而并沒有:laughing:。問題出在哪,原來,swift中如果需要對一個值進行監(jiān)聽,那么一定要記住2個關(guān)鍵詞

  • @objc
  • dynamic

否則,

沒有@objc程序在監(jiān)聽時會觸發(fā)奔潰;沒有dynamic則屬性的set方法不會生效,自然就沒有上面的打印,因為KVO的本質(zhì)就是監(jiān)聽屬性的set方法,而可變數(shù)組的增刪操作都不會生效;

但是為什么KVC的操作卻能生效呢?這是因為KVC內(nèi)部的實現(xiàn)過程是

  • [person willChangeValueForKey:@"age"];
  • person->_age = 10;
  • [person didChangeValueForKey:@"age"];
  • 而didChangeValueForKey:內(nèi)部會調(diào)用observe的observeValueForKeyPath:ofObject:change:context:的方法,也就觸發(fā)了KVO

所以正確的寫法應(yīng)該是

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)
  })
 }
}

到此這篇關(guān)于在Swift中使用KVO的細節(jié)以及內(nèi)部實現(xiàn)解析的文章就介紹到這了,更多相關(guān)Swift使用KVO內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Swift學(xué)習(xí)筆記之元組(tuples)

    Swift學(xué)習(xí)筆記之元組(tuples)

    這篇文章主要給大家介紹了Swift中元組(tuples)的相關(guān)資料,文中介紹的非常詳細,對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • swift實現(xiàn)自動輪播圖效果(UIScrollView+UIPageControl+Timer)

    swift實現(xiàn)自動輪播圖效果(UIScrollView+UIPageControl+Timer)

    這篇文章主要為大家詳細介紹了swift實現(xiàn)自動輪播圖效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Swift教程之方法詳解

    Swift教程之方法詳解

    這篇文章主要介紹了Swift教程之方法詳解,方法是關(guān)聯(lián)到一個特定類型的函數(shù),類、結(jié)構(gòu)、枚舉所有可以定義實例方法,封裝特定任務(wù)和功能處理給定類型的一個實例,需要的朋友可以參考下
    2015-01-01
  • Swift中內(nèi)置的集合類型學(xué)習(xí)筆記

    Swift中內(nèi)置的集合類型學(xué)習(xí)筆記

    Swift中自帶數(shù)組、set、字典三大集合類型,這里將學(xué)習(xí)過程中的基礎(chǔ)的Swift中內(nèi)置的集合類型學(xué)習(xí)筆記進行整理,需要的朋友可以參考下
    2016-06-06
  • swift相冊相機的權(quán)限處理示例詳解

    swift相冊相機的權(quán)限處理示例詳解

    在iOS7以后要打開手機攝像頭或者相冊的話都需要權(quán)限,在iOS9中更是更新了相冊相關(guān)api的調(diào)用,那么下面這篇文章主要給大家介紹了關(guān)于swift相冊相機權(quán)限處理的相關(guān)資料,文中給出了詳細的示例代碼,需要的朋友可以參考下。
    2017-10-10
  • Swift?Package?技巧及混編兼容問題詳解

    Swift?Package?技巧及混編兼容問題詳解

    這篇文章主要為大家介紹了Swift?Package?技巧及混編兼容問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Swift之運算符重載示例詳解

    Swift之運算符重載示例詳解

    這篇文章主要為大家介紹了Swift之運算符重載示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • RxSwift使用技巧之過濾操作詳解

    RxSwift使用技巧之過濾操作詳解

    RxSwift的目的是讓讓數(shù)據(jù)/事件流和異步任務(wù)能夠更方便的序列化處理,能夠使用Swift進行響應(yīng)式編程,下面這篇文章主要給大家介紹了關(guān)于RxSwift使用技巧之過濾操作的相關(guān)資料,需要的朋友可以參考下。
    2017-09-09
  • Swift Access Control訪問控制與斷言詳細介紹

    Swift Access Control訪問控制與斷言詳細介紹

    這篇文章主要介紹了Swift Access Control訪問控制與斷言,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09
  • Swift中轉(zhuǎn)義閉包示例詳解

    Swift中轉(zhuǎn)義閉包示例詳解

    在Swift 中的閉包類似于結(jié)構(gòu)塊,并可以在任何地方調(diào)用,下面這篇文章主要給大家介紹了關(guān)于Swift中轉(zhuǎn)義閉包的相關(guān)資料,需要的朋友可以參考下
    2021-11-11

最新評論