美文网首页kvo
iOS之KVO监听NSMutableArray

iOS之KVO监听NSMutableArray

作者: 无极战思 | 来源:发表于2020-06-25 17:33 被阅读0次

Demo地址: https://github.com/hanhuitao/KVO-NSMutableArray.git

iOS 中 KVO (key-value-observing) 的原理,简单来说就是重写了被观察属性的 set 方法,一般情况下只有通过调用 set 方法对值进行改变才会触发 KVO,直接访问实例变量修改值是不会触发 KVO 的。

先上代码

    #import "ViewController.h"
    @interface ViewController ()
    @property(nonatomic, strong)NSMutableArray * array;
    @end

    @implementation ViewController
    -(NSMutableArray*)array
    {
        if (!_array) {
            _array=[NSMutableArray new];
        }
        return _array;
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self.array addObjectsFromArray:@[@"黑色",@"白色"]];
        NSLog(@"初始化地址=%p",self.array);
        [self addObserver:self forKeyPath:@"array" options:NSKeyValueObservingOptionNew context:nil];

        
        
    }

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
    //    [self.array addObject:@"苍白色"];
     //   [[self mutableArrayValueForKey:@"array"]addObject:@"苍白色"];
        NSLog(@"改变数据源之后=%p",self.array);

    }


    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
    {
       
    NSLog(@"keyPath=%@,object=%@,change=%@,context=%@",keyPath,object,change,context);
        
        

    }

@end

我们注意看touchesBegan里面的两行代码
1.使用[self.array addObject:@"苍白色"]添加对象


无触发KVO.GIF

可以看出:是没有触发kvo的代理方法的,array的前后内存地址不变

2.使用 [[self mutableArrayValueForKey:@"array"]addObject:@"苍白色"]添加对象


KVO触发.GIF

可以看出:触发了kvo的代理方法的,并且array的前后内存地址发生了变化

为什么会这样:

NSMutableArray在调用它的 addObject、removeObject 系列方法时,并不会触发它自己的 set 方法。所以,对一个可变数组进行观察,在它加减元素时不会收到期望的消息。
因为KVO的本质是系统监测到\color{red} {某个属性的内存地址}或常量改变时,会添加上- (void)willChangeValueForKey:(NSString *)key和- (void)didChangeValueForKey:(NSString *)key方法来发送通知,所以一种解决方法是手动调用者两个方法,但是并不推荐,你永远无法像系统一样真正知道这个元素什么时候被改变。另一种便是利用使用mutableArrayValueForKey:了。

那么为什么mutableArrayValueForKey:这个方法可以监听dataSource内部变化呢?

mutableArrayValueForKey:默认采用的是搜索模式,在NSMutableArray搜索匹配insertObject:atIndex:和removeObjectAtIndex:等能引起容器内部Object发生改变的方法,如果发现至少一个插入或者删除方法,就会发送发送消息给原始接受者。

相关文章

网友评论

    本文标题:iOS之KVO监听NSMutableArray

    本文链接:https://www.haomeiwen.com/subject/xygsfktx.html