KVO原理及监听数组数量发生变化

kvo作用

KVO俗称键值监听,它提供一种机制,当指定的对象的属性被修改后,则对象就会接收到通知。就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知想要的观察者。

使用步骤:

步骤一 

给对象添加监听者

首先创建一个person类

@interface Person :NSObject

@property(nonatomic,copy) NSString *name;

@end



//在viewcontroller扩展中添加一个属性

@property(nonatomic,strong) Person *person;


//并给该属性初始化对象,并给属性添加kvo监听

self.person = [Person new];
[self.person addObserver:self forKeyPath:@"name"options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

具体参数说明:

  1. observer:观察者
  2.  forkeyPath参数是一个键值对中的键,唯一标示符绑定值。
  3. options:

             NSKeyValueObservingOptionNew:change字典包括改变后的值 

             NSKeyValueObservingOptionOld:   change字典包括改变前的值 

            NSKeyValueObservingOptionInitial: 注册后立刻触发KVO通知 

            NSKeyValueObservingOptionPrior:  值改变前是否也要通知

  4.     context:上下文,这个会传递到订阅者的函数中,用来区分消息,所以应当是不同的。

 步骤二

如果修改了person的name的值就会触发下面方法

//需要在这里实现监听后要做的操作

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

步骤三

删除指定Key路径的监听器:

在- (void)dealloc;方法中移除监听

扫描二维码关注公众号,回复: 9889335 查看本文章
- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath

- (void)removeObserver:(NSObject *)observer     forKeyPath:(NSString *)keyPath  context:(void *)context

 kvo原理

 主要用到了运行时(runtime)

当某个类的对象第一次被观察时,会通过运行时动态地创建对应于该类的一个派生类,在这个派生类中系统会重写父类中被观察属性的setter方法。然后根据options中的值来确定触发哪些方法,下面会触发改变前和改变后的方法。

-(void)setName:(NSString *)name{

    [self willChangeValueForKey:@"name"];//会在值即将发生变化时发送通知
    _name = name;
    [self didChangeVauleForKey:@"name"]; //会在值已经发生变化时发送通知

}

 automaticallyNotifiesObserversForKey该方法用于是否自动触发kvo,返回no要手动触发,


+(BOOL)automaticallyNotifiesObserversForKey:(NSString *)key{

    if([key isEqualToString:@"name"]){
        return NO;
    }

    return [super automaticallyNotifiesObserversForKey:key];

}

应用

商城购物车中都有一个全选按钮,如果每个商品都一一勾选后,那么全选按钮就会被自动选中。如果其中一个商品没有选中,然后全选按钮不会被选中。

这里需要监听加入购物车数组对象。


@interface ViewController ()

//下单数据源
@property(nonatomic,strong) NSMutableArray *pendingDataSource;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //监听pendingDataSource对象是否发生变化
    [self addObserver:self forKeyPath:@"pendingDataSource" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

}

-(void)addAction{
   [[self mutableArrayValueForKey:@"pendingDataSource"] addObject:person];
}

demo地址https://github.com/lijsrn/KVODemo

发布了47 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/a1034386099/article/details/100079274