iOS之KVO使用
// 建立监听
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullablevoid *)context;
// 处理监听
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullableid)object change:(nullable NSDictionary<NSKeyValueChangeKey,id> *)change context:(nullablevoid *)context;
// 移除监听
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
下面借用一张大神的图:
示例代码1:我们创建一个student类,使用KVO模式,给其中的username 属性添加监听。
被监听者(即被观察):
Student *st = [[Student alloc] init];
st.myName = @"张三";
st.myAge = 12;
建立监听:
[st addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
// st:被监听者
//Observer:观察者(处理被监听者),可以是self,也可以是其他对象
//KeyPath:被监听者属性,比如监听属性myName的变化,必须是一个与属性名称一致的字符串。
// options :监听类型// NSKeyValueObservingOptionNew,NSKeyValueObservingOptionOld这两个参数的意思是监听它的新值和旧值
// 触发方法,修改属性:st.myName = @"王五";
处理监听:
//观察者所在类,必须重写该方法,当观察到有值改变,自动执行以下方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPathisEqualToString:@"myName"]) {// keyPath就是上面添加观察者的时候创建的属性字符
// change字典中的old new是关键字,专门用来存储新值和老值
NSLog(@"旧值 === %@", [change objectForKey:@"old"]);
NSLog(@"新值 === %@", [change objectForKey:@"new"]);
}
}
示例代码2:
被监听者的代码如下
@interface ShopCartModel : NSObject
@property (nonatomic, copy) NSString *item_id;// id
@property (nonatomic, copy) NSString *count;//数量
@property (nonatomic, copy) NSString *item_size;//规格
@property (nonatomic, assign) BOOL isSelect;//是否选中
@property (nonatomic, assign) NSInteger type;//类型:1普通,2跨境
@property (nonatomic, strong) CommodityModel *item_info;//商品属性
@property (nonatomic, weak) ShopViewModel *vm;// ViewModel
@end
#import "ShopCartModel.h"
@implementation ShopCartModel
// 添加观察
- (void)setVm:(ShopViewModel *)vm {
_vm = vm;
// 观察者是其他对象
[selfaddObserver:vmforKeyPath:@"isSelect"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:NULL];
}
// 移除观察
-(void)dealloc {
[selfremoveObserver:_vmforKeyPath:@"isSelect"];
}
@end
观察者代码:
@interface ShopViewModel : NSObject
- (void)pitchOn:(NSMutableArray *)carDataArrList;
@end
@implementation ShopViewModel
// 选中
- (void)pitchOn:(NSMutableArray *)carDataArrList
{
for (int i =0; i < carDataArrList.count; i++) {
NSArray *dataList = [carDataArrListobjectAtIndex:i];
NSMutableDictionary *dic = [dataListlastObject];
for (int j=0; j<dataList.count-1; j++) {
ShopCartModel *model = (ShopCartModel *)[dataListobjectAtIndex:j];
// 普通商品
if (model.type==1 ) {
if (!model.isSelect && ![model.item_info.sale_stateisEqualToString:@"3"]) {// 售罄 3
[dic setObject:@"NO"forKey:@"checked"];
break;
}
}
}
}
}
// 监听结果。已在ShopCartModel中建立监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"开始计算价钱");
if ([keyPathisEqualToString:@"isSelect"]) {
NSLog(@"处理....");
}
}
@end