KVO
KVO(Key-Value-Observing):翻譯成鍵值觀察茂装。它是一種觀察者模式的衍生其馏。其基本思想是剧蹂,對目標(biāo)對象的某屬性添加觀察,當(dāng)該屬性發(fā)生變化時,通過觸發(fā)觀察者對象實現(xiàn)的KVO接口方法执桌,來自動的通知觀察者鄙皇。
KVO是觀察者模式的另一實現(xiàn),使用了isa混寫(isa-swizzling)來實現(xiàn)KVO仰挣。
KVO底層實現(xiàn):
當(dāng)某個類的對象第一次被觀察時伴逸,系統(tǒng)就會在運行時動態(tài)地創(chuàng)建該類的一個派生類,在這個派生類中重寫原類中被觀察屬性的setter方法,派生類在被重寫的setter方法實現(xiàn)真正的通知機制(Person->NSKVONotifying_Person). 派生類重寫了 class 方法以“欺騙”外部調(diào)用者它就是起初的那個類膘壶。然后系統(tǒng)將這個對象的 isa指針指向這個新誕生的派生類错蝴,因此這個對象就成為該派生類的對象了,因而在該對象上對 setter的調(diào)用就會調(diào)用重寫的setter颓芭,從而激活鍵值通知機制顷锰。此外,派生類還重寫了dealloc 方法來釋放資源亡问。
KVO的使用場景:
?1.實現(xiàn)上下拉刷新控件?content offset
?2.webview混合排版?content size
?3.監(jiān)聽模型屬性實時更新UI
KVO總結(jié)
1.動態(tài)創(chuàng)建Person的子類使用
2.子類重寫setName
3.動態(tài)修改了對象的類型
4.還了解到了,KVO不僅可以調(diào)用setter方法,還可以調(diào)用插入,刪除,代替方法.通過對kvo的進一步了解,我們是很清楚KVO底層運用.
KVO與Notification之間的區(qū)別:
notification是需要一個發(fā)送notification的對象官紫,一般是notificationCenter,來通知觀察者州藕。
KVO是直接通知到觀察對象束世,并且邏輯非常清晰,實現(xiàn)步驟簡單床玻。
KVC
KVC(Key-value coding)鍵值編碼良狈,就是指iOS的開發(fā)中,可以允許開發(fā)者通過Key名直接訪問對象的屬性笨枯,或者給對象的屬性賦值薪丁。而不需要調(diào)用明確的存取方法。這樣就可以在運行時動態(tài)地訪問和修改對象的屬性馅精。而不是在編譯時確定严嗜,這也是iOS開發(fā)中的黑魔法之一。很多高級的iOS開發(fā)技巧都是基于KVC實現(xiàn)的洲敢。
KVC底層實現(xiàn):
(1.)KVC取值:
1.首先按get<Key>,<key>,is<Key>的順序方法查找getter方法漫玄,找到的話會直接調(diào)用。如果是BOOL或者Int等值類型压彭, 會將其包裝成一個NSNumber對象睦优。
2.如果上面的getter沒有找到,KVC則會查找countOf<Key>,objectIn<Key>AtIndex或<Key>AtIndexes格式的方法壮不。如果countOf<Key>方法和另外兩個方法中的一個被找到汗盘,那么就會返回一個可以響應(yīng)NSArray所有方法的代理集合(它是NSKeyValueArray,是NSArray的子類)询一,調(diào)用這個代理集合的方法隐孽,或者說給這個代理集合發(fā)送屬于NSArray的方法癌椿,就會以countOf<Key>,objectIn<Key>AtIndex或<Key>AtIndexes這幾個方法組合的形式調(diào)用。還有一個可選的get<Key>:range:方法菱阵。所以你想重新定義KVC的一些功能踢俄,你可以添加這些方法,需要注意的是你的方法名要符合KVC的標(biāo)準命名方法晴及,包括方法簽名都办。
3.如果上面的方法沒有找到,那么會同時查找countOf虑稼,enumeratorOf,memberOf格式的方法脆丁。如果這三個方法都找到,那么就返回一個可以響應(yīng)NSSet所的方法的代理集合动雹,和上面一樣槽卫,給這個代理集合發(fā)NSSet的消息,就會以countOf胰蝠,enumeratorOf,memberOf組合的形式調(diào)用歼培。
4.如果還沒有找到,再檢查類方法+(BOOL)accessInstanceVariablesDirectly,如果返回YES(默認行為)茸塞,那么和先前的設(shè)值一樣躲庄,會按_,_is,,is的順序搜索成員變量名,這里不推薦這么做钾虐,因為這樣直接訪問實例變量破壞了封裝性噪窘,使代碼更脆弱。如果重寫了類方法+(BOOL)accessInstanceVariablesDirectly返回NO的話效扫,那么會直接調(diào)用valueForUndefinedKey:方法倔监,默認是拋出異常。
(2.)KVC設(shè)值:
1.程序優(yōu)先調(diào)用set<Key>:屬性值方法菌仁,代碼通過setter方法完成設(shè)置
2.如果沒有找到setName:方法浩习,KVC機制會檢查+(BOOL)accessInstanceVariablesDirectly方法
3.如果該類即沒有set<key>:方法,也沒有_<key>成員變量济丘,KVC機制會搜索_is<Key>的成員變量谱秽。
4.和上面一樣,如果該類即沒有set<Key>:方法摹迷,也沒有_<key>和_is<Key>成員變量疟赊,KVC機制再會繼續(xù)搜索<key>和is<Key>的成員變量。再給它們賦值峡碉。
5.如果上面列出的方法或者成員變量都不存在近哟,系統(tǒng)將會執(zhí)行該對象的setValue:forUndefinedKey:方法,默認是拋出異常异赫。
KVC的使用場景:
1.KVC設(shè)值
2.KVC取值
3.KVC使用keyPath
4.KVC處理異常
5.KVC處理數(shù)值和結(jié)構(gòu)體類型屬性
6.KVC鍵值驗證(Key-Value Validation)
7.KVC處理集合
8.KVC處理字典