KVO與KVC

KVO

KVO:鍵值觀察。觀察者模式的衍生,對(duì)目標(biāo)對(duì)象的屬性添加觀察,當(dāng)該屬性發(fā)生變化時(shí),通過觸發(fā)觀察者對(duì)象實(shí)現(xiàn)KVO接口方法,來自動(dòng)的通知觀察者。

KVO底層實(shí)現(xiàn):某個(gè)類的對(duì)象第一次被觀察時(shí),系統(tǒng)會(huì)在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建該類的一個(gè)派生類,并在派生類中重寫setter方法,在setter方法實(shí)現(xiàn)真正的通知機(jī)制(如:Person-》NSKVONotifying_Person),外部調(diào)用的類其實(shí)調(diào)用的是這個(gè)派生類。系統(tǒng)對(duì)象的isa指針指向新的派生類,對(duì)setter的調(diào)用就激活鍵值通知機(jī)制。

KVO與Notification之間的區(qū)別:

notification是需要一個(gè)發(fā)送notification的對(duì)象,一般是notificationCenter,來通知觀察者

KVO是直接通知到觀察對(duì)象,并且邏輯非常清晰,實(shí)現(xiàn)步驟簡(jiǎn)單

KVO?例子:

? ? 添加觀察者:? ?[a ????addObserver:b? ? forKeyPath:@"name"? ? options:kNilOptions? ? ?context:nil];? ??

? ? 在觀察者中實(shí)現(xiàn)監(jiān)聽方法,observeValueForKeyPath: ofObject: change: context:

? ? 移除觀察者:? ? [a? ? removeObserver:b? forKeyPath:@"name"];

? ? 數(shù)據(jù)修改:? ? a.name = @"zzz"

KVC

KVC:鍵值編碼。開發(fā)者通過key名直接訪問對(duì)象的屬性,或者給對(duì)象的屬性賦值,而不需要調(diào)用明確的存取方法。這樣就可以在運(yùn)行時(shí)動(dòng)態(tài)訪問和修改對(duì)象的屬性,而不是在編譯時(shí)確定。

KVC底層實(shí)現(xiàn):

(1).KVC取值:

? ? 1.首先查找getter方法,找到的話直接調(diào)用。如果是BOOL或者Int等值,將其包裝成一個(gè)NSNumber對(duì)象。

? ? 2.如果對(duì)象的getter沒有找到,KVC則會(huì)查找countOf,objectInAtIndex或AtIndexes格式的方法。如果找到countOf和(objectInAtIndex或AtIndexes中的一個(gè)),那么就會(huì)返回一個(gè)可以響應(yīng)NSArray所有方法的代理集合(NSKeyValueArray,是BSArray的子類)。

? ? 3.如果上面的方法都沒有找到,那么會(huì)同時(shí)查找countOf,enumeratorOf,memberOf格式的方法。如果都找到,返回一個(gè)可以響應(yīng)NSSet所有的方法的代理集合。

? ? 4.如果還沒有找到,再檢查類方法+(BOOL)accessInstanceVariablesDirectly,如果返回YES,會(huì)按照_,_is,is的順序搜索成員變量。不推薦這樣做。如果重寫+(BOOL)accessInstanceVariablesDirectly返回NO的話,那么會(huì)直接調(diào)用valueForUndefinedKey:方法,默認(rèn)是拋出異常。

(2).KVC設(shè)值:

? ? 1.程序優(yōu)先調(diào)用set屬性值方法,代碼通過setter方法完成設(shè)置

? ? 2.如果沒有找到setName方法,KVC機(jī)制會(huì)檢查+(BOOL)accessInstanceVariablesDirectly方法

? ? 3.如果該類即沒有set方法,也沒有_成員變量,KVC機(jī)制會(huì)搜索_is的成員變量

? ? 4.和上面一樣,沒有set方法,也沒有_和_is成員變量,KVC機(jī)制再會(huì)繼續(xù)搜索和is的成員變量

? ? 5.如果上面列出的方法或者變量都不存在,系統(tǒng)將會(huì)執(zhí)行該對(duì)象的setValue:forUndefinedKey:方法,默認(rèn)跑出異常

(3).KVC 例子

? ? ?1.對(duì)私有變量進(jìn)行賦值:[p setValue:@"張三"? ? forKey:@"name"]? ? [p setValue:@200? ? forKeyPath:@"dog.weight"]

? ? ?2.字典轉(zhuǎn)模型? ? [self? ? setValuesForKeysWithDictionary:dict]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容