一.KVO
KVO的全稱為Key-Value Observing伤极,也就是我們常說的鍵值監(jiān)聽。通過KVO我們可以監(jiān)聽某個對象的屬性的改變
1.KVO的使用
1.給對象添加KVO監(jiān)聽
NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
[self.person addObserver:self forKeyPath:@"age" options:options context:@"context"];
2.當監(jiān)聽對象的屬性值發(fā)生改變的時候會調(diào)用下面的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
NSLog(@"監(jiān)聽到%@的%@屬性值改變了 - %@ - %@", object, keyPath, change, context);
}
3.當內(nèi)存銷毀的時候移除KVO監(jiān)聽
- (void)dealloc {
[self.person removeObserver:self forKeyPath:@"age"];
}
2.KVO的本質(zhì)
- KVO的本質(zhì)其實是利用RuntimeAPI動態(tài)生成一個子類汽纠,并且讓instance對象的isa指向這個全新的子類。
- 所以當我們修改instance對象的屬性時找蜜,會調(diào)用Foundation的_NSSetXXXValueAndNotify函數(shù)干跛,即:
. willChangeValueForKey:
. 父類原來的setter
.didChangeValueForKey:
接下來內(nèi)部會觸發(fā)監(jiān)聽器(Oberser)的監(jiān)聽方法(observeValueForKeyPath:ofObject:Change:Context:)
面試問題:
如何手動出發(fā)KVO
只要手動調(diào)用willChangeValueForKey和didChangeValueForKey:方法即可直接修改成員變量會觸發(fā)KVO嗎?
并不會酝润,因為本質(zhì)是動態(tài)生成一個子類中燎竖,調(diào)用上訴的三個方法,但是直接修改并沒有調(diào)用要销。
二.KVC
- KVC的全稱是Key-Value Coding构回,俗稱“鍵值編碼”,可以通過一個key來訪問某個屬性
- 常見的API有
. (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
. (void)setValue:(id)value forKey:(NSString *)key;
. (id)valueForKeyPath:(NSString *)keyPath;
. (id)valueForKey:(NSString *)key;