• 使用KVO监听数组的变化


    以前有个需求,需要监听数组长度的变化。使用KVO直接监听数组本身,由于数组地址并没有发生改变,所以并不能监听到。试了好多方法,都没有能够实现。知道最近听的一场公开课中,才掌握了正确的监听方法

    先举个错误的例子

    @interface ViewController ()
    @property (nonatomic, strong) NSMutableArray *array;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self.array addObserver:self forKeyPath:@"count" options:(NSKeyValueObservingOptionNew) context:nil];
    }

    这样会直接报错,NSMutableArray 没有 count的 keyPath。

    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '[<__NSArrayM 0x282195770> addObserver:forKeyPath:options:context:] is not supported. Key path: count'

    正确的打开方式是这样的,不多说废话,直接上代码

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (nonatomic, strong) NSMutableArray *array;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        [self addObserver:self forKeyPath:NSStringFromSelector(@selector(array)) options:(NSKeyValueObservingOptionNew) context:nil];
    }
    
    
    
    - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context {
        
        /*
         typedef NS_ENUM(NSUInteger, NSKeyValueChange) {
         NSKeyValueChangeSetting = 1,
         NSKeyValueChangeInsertion = 2,
         NSKeyValueChangeRemoval = 3,
         NSKeyValueChangeReplacement = 4,
         };
         */
    
        
        //第一次触发是添加一条数据,kind为2,对应的是NSKeyValueChangeInsertion
        /*
         {
        indexes = "<_NSCachedIndexSet: 0x280495620>[number of indexes: 1 (in 1 ranges), indexes: (0)]";
        kind = 2;
        new =     (
                   "NewData- 1"
                   );
         }
         */
        
        
        //第二次触发是修改一条数据,kind为4,对应的是NSKeyValueChangeReplacement
        /*
         {
         indexes = "<_NSCachedIndexSet: 0x280495620>[number of indexes: 1 (in 1 ranges), indexes: (0)]";
         kind = 4;
         new =     (
         "NewData- 2"
         );
         }
         */
        
        //第三次次触发是删除一条数据,kind为3,对应的是NSKeyValueChangeRemoval
        /*
         {
         indexes = "<_NSCachedIndexSet: 0x280495620>[number of indexes: 1 (in 1 ranges), indexes: (0)]";
         kind = 3;
         }
         */
        
        
        NSLog(@"我触发了");
    }
    
    
    
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        static NSInteger a = 0;
        a++;
        
        //这一步特别重要
        NSMutableArray *tempArray = [self mutableArrayValueForKey:NSStringFromSelector(@selector(array))];
        if (1 == a) {//插入一条
            [tempArray addObject:[NSString stringWithFormat:@"NewData- %tu",a]];
        } else if (2 == a) {//修改一条
            tempArray[0] = [NSString stringWithFormat:@"NewData- %tu",a];
        } else if (3 == a) {
            [tempArray removeAllObjects];
        }
    }
    
    
    - (NSMutableArray *)array {
        if (!_array) {
            _array = [NSMutableArray array];
        }
        return _array;
    }
    
    - (void)dealloc {
        [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(array))];
    }
    

     KVO三部曲,注册监听,实现代理方法,移除监听。

    在监听数组变化时,需要特别注意,

        NSMutableArray *tempArray = [self mutableArrayValueForKey:NSStringFromSelector(@selector(array))];
    

     一定要使用该方法复制出一个数组,而不是使用数组本身进行操作。

  • 相关阅读:
    Pod镜像拉取策略imagePullPolicy
    部署helm服务
    查看k8s中etcd数据
    k8s RBAC实践
    部署k8s集群监控Heapster
    编译k8s1.11 kube-apiserver源码
    阿里云跨地域访问私网
    阿里云ECS搭建harbor1.6.1仓库
    JavaScript
    前端之网络协议、浏览器
  • 原文地址:https://www.cnblogs.com/funny11/p/10058837.html
Copyright © 2020-2023  润新知