KVO
KVO:鍵值觀察得问。觀察者模式的衍生囤攀,對目標(biāo)對象的屬性添加觀察,當(dāng)該屬性發(fā)生變化時(shí)宫纬,通過觸發(fā)觀察者對象實(shí)現(xiàn)KVO接口方法峰髓,來自動的通知觀察者良蛮。
KVO底層實(shí)現(xiàn):某個(gè)類的對象第一次被觀察時(shí)钉跷,系統(tǒng)會在運(yùn)行時(shí)動態(tài)創(chuàng)建該類的一個(gè)派生類该编,并在派生類中重寫setter方法,在setter方法實(shí)現(xiàn)真正的通知機(jī)制(如:Person-》NSKVONotifying_Person)认境,外部調(diào)用的類其實(shí)調(diào)用的是這個(gè)派生類胚委。系統(tǒng)對象的isa指針指向新的派生類,對setter的調(diào)用就激活鍵值通知機(jī)制叉信。
KVO與Notification之間的區(qū)別:
notification是需要一個(gè)發(fā)送notification的對象亩冬,一般是notificationCenter,來通知觀察者
KVO是直接通知到觀察對象硼身,并且邏輯非常清晰硅急,實(shí)現(xià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名直接訪問對象的屬性营袜,或者給對象的屬性賦值,而不需要調(diào)用明確的存取方法丑罪。這樣就可以在運(yùn)行時(shí)動態(tài)訪問和修改對象的屬性荚板,而不是在編譯時(shí)確定。
KVC底層實(shí)現(xiàn):
(1).KVC取值:
? ? 1.首先查找getter方法吩屹,找到的話直接調(diào)用跪另。如果是BOOL或者Int等值,將其包裝成一個(gè)NSNumber對象煤搜。
? ? 2.如果對象的getter沒有找到免绿,KVC則會查找countOf,objectInAtIndex或AtIndexes格式的方法擦盾。如果找到countOf和(objectInAtIndex或AtIndexes中的一個(gè))嘲驾,那么就會返回一個(gè)可以響應(yīng)NSArray所有方法的代理集合(NSKeyValueArray淌哟,是BSArray的子類)。
? ? 3.如果上面的方法都沒有找到距淫,那么會同時(shí)查找countOf绞绒,enumeratorOf婶希,memberOf格式的方法榕暇。如果都找到,返回一個(gè)可以響應(yīng)NSSet所有的方法的代理集合喻杈。
? ? 4.如果還沒有找到彤枢,再檢查類方法+(BOOL)accessInstanceVariablesDirectly,如果返回YES筒饰,會按照_,_is,is的順序搜索成員變量缴啡。不推薦這樣做。如果重寫+(BOOL)accessInstanceVariablesDirectly返回NO的話瓷们,那么會直接調(diào)用valueForUndefinedKey:方法业栅,默認(rèn)是拋出異常。
(2).KVC設(shè)值:
? ? 1.程序優(yōu)先調(diào)用set屬性值方法谬晕,代碼通過setter方法完成設(shè)置
? ? 2.如果沒有找到setName方法碘裕,KVC機(jī)制會檢查+(BOOL)accessInstanceVariablesDirectly方法
? ? 3.如果該類即沒有set方法,也沒有_成員變量攒钳,KVC機(jī)制會搜索_is的成員變量
? ? 4.和上面一樣帮孔,沒有set方法,也沒有_和_is成員變量不撑,KVC機(jī)制再會繼續(xù)搜索和is的成員變量
? ? 5.如果上面列出的方法或者變量都不存在文兢,系統(tǒng)將會執(zhí)行該對象的setValue:forUndefinedKey:方法,默認(rèn)跑出異常
(3).KVC 例子
? ? ?1.對私有變量進(jìn)行賦值:[p setValue:@"張三"? ? forKey:@"name"]? ? [p setValue:@200? ? forKeyPath:@"dog.weight"]
? ? ?2.字典轉(zhuǎn)模型? ? [self? ? setValuesForKeysWithDictionary:dict]