一、KVO介紹
KVO就是觀察者模式,說白了就是你關心的一個值改變了,你就會得到通知。你就可以在你想處理的地方處理這個值。
二、KVO的使用
一般分為三步:
- 注冊監聽
使用方法:
/** * 添加KVO監聽者 * * @param observer 觀察者(監聽器) * @param keyPath 屬性名(要觀察的屬性) * @param options * @param context 傳遞的參數 */ - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
例子:
//為對象p添加一個觀察者(監聽器) [p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"test"];
2.設置監聽事件
/** * 當利用KVO監聽到某個對象的屬性值發生了改變,就會自動調用這個 * * @param keyPath 哪個屬性被改了 * @param object 哪個對象的屬性被改了 * @param change 改成咋樣 * @param context 當初addObserver時的context參數值 */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"%@ %@ %@ %@", object, keyPath, change, context); }
3.取消監聽
//釋放KVO監聽 -(void)dealloc { [p removeObserver:self forKeyPath:@"test"]; }
# iOS 中KVC的總結 ##
一、 KVC介紹
kvc就是鍵值編碼(key-value),說白了就是通過指定的key獲得想要的值value。而不是通過調用Setter、Getter方法訪問。*
二、 KVC的強大之處
1 .訪問私有變量
一個類中的私有變量,不能直接通過Setter、Getter方法訪問。但是卻可以通過KVC來訪問。舉例:
一個類如下:
@interface Dog : NSObject { @private double height; }
這里的私有變量 height ,假如直接使用Setter、Getter方法訪問,就會出現下面的錯誤。

這時候可以使用KVC來訪問這個私有變量:
Dog *dog = [[Dog alloc]init]; [dog setValue:@12 forKey:@"height"];//給私有變量賦值 NSLog(@"dog's height is = %@",[dog valueForKey:@"height"]);//讀取私有變量的值
- 實際使用舉例
利用kvc的這個特性,我們可以訪問系統里的一些私有變量。
例如:在UIPageControl里面有兩個私有變量:
UIImage* _currentPageImage; UIImage* _pageImage;
我們可以通過kvc來進行讀取和賦值:
UIPageControl *pageControl = [[UIPageControl alloc]init];
//設置值 [pageControl setValue:[UIImage imageNamed:@"XX"] forKeyPath:@"_currentPageImage"]; [pageControl setValue:[UIImage imageNamed:@"XX"] forKeyPath:@"_pageImage"]; //讀取值 UIImage *currentImage = [pageControl valueForKey:@"_currentPageImage"]; UIImage *pageImage = [pageControl valueForKey:@"_pageImage"];
這樣我們就可以設置當前顯示和未顯示到腳標的樣式了。
2. 使用KVC直接訪問 NSArray 或者 NSSet 的屬性值
NSArray/NSSet等都支持KVC,這里舉一個例子:
NSArray *books= @[book1, book2, book3]; NSArray *names = [books valueForKeyPath:@"name"]; NSLog(@"%@", [books valueForKeyPath:@"@avg.price"]);//使用kvc直接打印出來書的平均價格
其中,book是一個書類,有一個屬性是name,一個屬性是price。
3. 使用KVC將字典(json)轉化成模型
// 定義一個字典 NSDictionary *dict = @{ @"name" : @"jack", @"money" : @"20.7", }; // 創建模型 Person *p = [[Person alloc] init]; // 字典轉模型 [p setValuesForKeysWithDictionary:dict]; NSLog(@"person's name is the %@",p.name); }
注意:
(1). key的值必須正確,如果拼寫錯誤,會出現異常
(2). 當key的值是沒有定義的,valueForUndefinedKey:這個方法會被調用,如果你自己寫了這個方法,key的值出錯就會調用到這里來
(3). 因為類key反復嵌套,所以有個keyPath的概念,keyPath就是用.號來把一個一個key鏈接起來,這樣就可以根據這個路徑訪問下去
(4). NSArray/NSSet等都支持KVC
