一、介紹:
KVO是一種能動態監聽到屬性值的改變的方式,使用場景非常廣泛,這里我只講如何監聽控制器ViewController中數組的變化。
二、了解:
首先我們應該知道KVO是不能直接監聽控制器ViewController數組的變化的,需要將數組定義在模型中,然后控制器ViewController持有模型對象,通過該對象才能監聽。
三、步驟:
<1>在控制器ViewController類中定義一個模型類Model,並在該類中聲明一個可變的數組屬性modelArray並進行懶加載,其實它最終就是作為控制器ViewController的數組使用;
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end /** * 在控制器新定義一個模型類 */ @interface Model : NSObject /** * 可變的數組 */ @property (strong,nonatomic)NSMutableArray *modelArray; @end
#import "ViewController.h"
@implementation ViewController
@end
@implementation Model /** * 懶加載 */ -(NSMutableArray *)modelArray{ if(!_modelArray){ _modelArray = [NSMutableArray array]; } return _modelArray; } @end
<2>在控制器ViewController中持有模型類Model的全局對象;
#import "ViewController.h" @interface ViewController () /** * 持有模型對象 */ @property (strong,nonatomic)Model *model; @end
<3>用第2步創建的對象注冊監聽,監聽屬性就是數組modelArray,即modelArray作為keyPath值,注冊方法為;
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
//注冊KVO監聽 [_model addObserver:self forKeyPath:@"modelArray" options:NSKeyValueObservingOptionNew context:nil];
<4>重寫監聽方法,監聽值的變化;
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context;
//重寫監聽方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"modelArray"]) { NSLog(@"%ld",_model.modelArray.count); } }
<5>移除監聽,最后釋放內內存時需要把監聽移除掉
-(void)dealloc{ [_model removeObserver:self forKeyPath:@"modelArray"]; }
<6>點擊界面,模擬數據添加到數組中,添加方法必須是:- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSObject *obj = [[NSObject alloc]init]; [[_model mutableArrayValueForKeyPath:@"modelArray"] addObject:obj]; }
四、演示截圖:(每點擊一次,能夠監聽到數組個數增加1)

五、完整代碼如下:
.h文件
// // ViewController.h // KVOTest // // Created by 夏遠全 on 16/11/23. // Copyright © 2016年 廣州市東德網絡科技有限公司. All rights reserved. // #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end /** * 在控制器新定義一個模型類 */ @interface Model : NSObject /** * 可變的數組 */ @property (strong,nonatomic)NSMutableArray *modelArray; @end
.m文件
// // ViewController.m // KVOTest // // Created by 夏遠全 on 16/11/23. // Copyright © 2016年 廣州市東德網絡科技有限公司. All rights reserved. // #import "ViewController.h" @interface ViewController () /** * 持有模型對象 */ @property (strong,nonatomic)Model *model; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //1.創建模型對象 _model = [[Model alloc]init]; //2.注冊KVO監聽 [_model addObserver:self forKeyPath:@"modelArray" options:NSKeyValueObservingOptionNew context:nil]; } /** * 3.重寫監聽方法 */ -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"modelArray"]) { NSLog(@"%ld",_model.modelArray.count); } } /** * 4.移除監聽 */ -(void)dealloc{ [_model removeObserver:self forKeyPath:@"modelArray"]; } /** * 5.模擬往數組添加數據 */ -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSObject *obj = [[NSObject alloc]init]; [[_model mutableArrayValueForKeyPath:@"modelArray"] addObject:obj]; } @end @implementation Model /** * 懶加載 */ -(NSMutableArray *)modelArray{ if(!_modelArray){ _modelArray = [NSMutableArray array]; } return _modelArray; } @end
注明:本人原創,牛人可以路過,希望可以幫到小白,嘿嘿😋
歡迎關注github:https://github.com/xiayuanquan
