欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

KVO是什么?

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

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

實(shí)現(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 的實(shí)現(xiàn)依賴于 Objective-C 強(qiáng)大的 Runtime【可參考:Runtime的幾個(gè)小例子】 ,從以上Apple 的文檔可以看出蘋果對(duì)于KVO機(jī)制的實(shí)現(xiàn)是一筆帶過,而具體的細(xì)節(jié)沒有過多的描述,但是我們可以通過Runtime的所提供的方法去探索,關(guān)于KVO機(jī)制的底層實(shí)現(xiàn)原理。為此啊左從網(wǎng)上的一些關(guān)于KVO的資料總結(jié)了有關(guān)的內(nèi)容:

基本的原理:

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

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

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

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

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

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

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

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

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

在外部我們,初始化一個(gè)對(duì)象,并對(duì)age進(jìn)行賦值,如下

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

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

  • @objc
  • dynamic

否則,

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

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

  • [person willChangeValueForKey:@"age"];
  • person->_age = 10;
  • [person didChangeValueForKey:@"age"];
  • 而didChangeValueForKey:內(nèi)部會(huì)調(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的細(xì)節(jié)以及內(nèi)部實(shí)現(xiàn)解析的文章就介紹到這了,更多相關(guān)Swift使用KVO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

    swift實(shí)現(xiàn)自動(dòng)輪播圖效果(UIScrollView+UIPageControl+Timer)

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

    Swift教程之方法詳解

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

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

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

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

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

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

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

    Swift之運(yùn)算符重載示例詳解

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

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

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

    Swift Access Control訪問控制與斷言詳細(xì)介紹

    這篇文章主要介紹了Swift Access Control訪問控制與斷言,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(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

最新評(píng)論