写作本文来由:   iOS默认不支持对数组的KVO,因为普通方式监听的对象的地址的变化,而数组地址不变,而是里面的值发生了改变

整个过程需要三个步骤 (与普通监听一致)

/*

*  第一步 建立观察者及观察的对象

*  第二步 处理key的变化(根据key的变化刷新UI)

*  第三步 移除观察者

*/

[objc] view plaincopy

数组不能放在UIViewController里面,在这里面的数组是监听不到数组大小的变化的,需要将需要监听的数组封装到model里面<

model类为: 将监听的数组封装到model里,不能监听UIViewController里面的数组

两个属性 一个 字符串类的姓名,一个数组类的modelArray,我们需要的就是监听modelArray里面元素的变化

[objc] view plaincopy

@interface model : NSObject  
    @property(nonatomic, copy)NSString *name;  
    @property(nonatomic, retain)NSMutableArray *modelArray;

1 建立观察者及观察的对象

第一步  建立观察者及观察的对象

[_modeladdObserver:selfforKeyPath:@"modelArray"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:NULL];

第二步 处理key的变化(根据key的变化刷新UI)

最重要的就是添加数据这里

[objc] view plaincopy

不能这样 [_model.modelArray addObject]方法,需要这样调用   [[_model mutableArrayValueForKey:@"modelArray"] addObject:str];原因稍后说明。

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

[objc] view plaincopy

{  
        if ([keyPath isEqualToString:@"modelArray"]) {  
            [_tableView reloadData];  
        }  
    }

第三步 移除观察者

[objc] view plaincopy

if (_model != nil) {  
        [_model removeObserver:self forKeyPath:@"modelArray"];  
    }

以下附上本文代码:

代码中涉及三点

1 根据数组动态刷新tableview;

2 定时器的使用(涉及循环引用问题);

3 使用KVC优化model的初始化代码。

没找到上传整个工程的方法,暂时附上代码

1  NSTimer相关

[objc] view plaincopy

//  
    //  NSTimer+DelegateSelf.h  
    //  KVOTableview  
    //  
    //  Created by 程立彬 on 14-8-8.  
    //  Copyright (c) 2014年 chenglb. All rights reserved.  
    //  
      
    //为防止controller和nstimer之间的循环引用,delegate指向当前单例,而不指向controller  
      
    #import <Foundation/Foundation.h>  
      
    @interface NSTimer (DelegateSelf)  
      
    +(NSTimer *)scheduledTimerWithTimeInterval:(int)timeInterval block:(void(^)())block repeats:(BOOL)yesOrNo;  
      
    @end

[objc] view plaincopy

//  
    //  NSTimer+DelegateSelf.m  
    //  KVOTableview  
    //  
    //  Created by 程立彬 on 14-8-8.  
    //  Copyright (c) 2014年 chenglb. All rights reserved.  
    //  
      
    #import "NSTimer+DelegateSelf.h"  
      
    @implementation NSTimer (DelegateSelf)  
      
    +(NSTimer *)scheduledTimerWithTimeInterval:(int)timeInterval block:(void(^)())block repeats:(BOOL)yesOrNo  
    {  
        return [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(callBlock:) userInfo:[block copy] repeats:yesOrNo];  
    }  
      
      
    +(void)callBlock:(NSTimer *)timer  
    {  
        void(^block)() = timer.userInfo;  
        if (block != nil) {  
            block();  
        }  
    }  
      
    @end

2 model相关

[objc] view plaincopy

//  
    //  model.h  
    //  KVOTableview  
    //  
    //  Created by 程立彬 on 14-8-8.  
    //  Copyright (c) 2014年 chenglb. All rights reserved.  
    //  
      
    #import <Foundation/Foundation.h>  
      
    @interface model : NSObject  
    @property(nonatomic, copy)NSString *name;  
    @property(nonatomic, retain)NSMutableArray *modelArray;  
      
    -(id)initWithDic:(NSDictionary *)dic;  
      
    @end

[objc] view plaincopy

//  
    //  model.m  
    //  KVOTableview  
    //  
    //  Created by 程立彬 on 14-8-8.  
    //  Copyright (c) 2014年 chenglb. All rights reserved.  
    //  
      
      
    //KVC的应用  简化冗余代码  
    #import "model.h"  
      
    @implementation model  
      
    -(id)initWithDic:(NSDictionary *)dic  
    {  
        self = [super init];  
        if (self) {  
            [self setValuesForKeysWithDictionary:dic];  
        }  
          
        return self;  
    }  
      
    -(void)setValue:(id)value forUndefinedKey:(NSString *)key  
    {  
        NSLog(@"undefine key ---%@",key);  
    }  
      
    @end

3 UIViewController相关

[objc] view plaincopy

//  
    //  RootViewController.m  
    //  KVOTableview  
    //  
    //  Created by 程立彬 on 14-8-8.  
    //  Copyright (c) 2014年 chenglb. All rights reserved.  
    //  
      
    /*
        *  第一步 建立观察者及观察的对象
        *  第二步 处理key的变化(根据key的变化刷新UI)
        *  第三步 移除观察者
      
    */  
      
    #import "RootViewController.h"  
    #import "NSTimer+DelegateSelf.h"  
    #import "model.h"  
      
    #define TimeInterval 3.0  
      
    @interface RootViewController ()<UITableViewDelegate,UITableViewDataSource>  
      
    @property(nonatomic, retain)NSTimer *timer;  
    @property(nonatomic, retain)UITableView    *tableView;  
    @property(nonatomic, retain)model *model;  
      
    @end  
      
    @implementation RootViewController  
      
    - (void)dealloc  
    {  
        //第三步  
        if (_model != nil) {  
            [_model removeObserver:self forKeyPath:@"modelArray"];  
        }  
        //停止定时器  
        if (_timer != nil) {  
            [_timer invalidate];  
            _timer = nil;  
        }  
    }  
      
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
    {  
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
        if (self) {  
      
            NSDictionary *dic = [NSDictionary dictionaryWithObject:[NSMutableArray arrayWithCapacity:0] forKey:@"modelArray"];  
              
            self.model = [[model alloc] initWithDic:dic];  
          
        }  
        return self;  
    }  
      
    - (void)viewDidLoad  
    {  
        [super viewDidLoad];  
          
        //第一步  
        [_model addObserver:self forKeyPath:@"modelArray" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];  
          
        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];  
        _tableView.delegate        = self;  
        _tableView.dataSource      = self;  
        _tableView.backgroundColor = [UIColor lightGrayColor];  
        [self.view addSubview:_tableView];  
          
        //定时添加数据  
        [self startTimer];  
          
    }  
      
    //添加定时器  
    -(void)startTimer  
    {  
        __block RootViewController *bself = self;  
          
        _timer = [NSTimer scheduledTimerWithTimeInterval:TimeInterval block:^{  
              
            [bself changeArray];  
        } repeats:YES];  
      
    }  
      
    //增加数组中的元素 自动刷新tableview  
    -(void)changeArray  
    {  
          
        NSString *str = [NSString stringWithFormat:@"%d",arc4random()%100];  
        [[_model mutableArrayValueForKey:@"modelArray"] addObject:str];  
          
    }  
      
      
    //第二步 处理变化  
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context  
    {  
        if ([keyPath isEqualToString:@"modelArray"]) {  
            [_tableView reloadData];  
        }  
    }  
      
      
      
      
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
    {  
        return  [_model.modelArray count];  
    }  
      
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;  
    {  
        static NSString *cellidentifier = @"cellIdentifier";  
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier];  
        if (cell == nil) {  
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier];  
        }  
          
        cell.textLabel.text = _model.modelArray[indexPath.row];  
        return cell;  
    }  
      
      
    - (void)didReceiveMemoryWarning  
    {  
        [super didReceiveMemoryWarning];  
        // Dispose of any resources that can be recreated.  
    }  
      
    @end

转载于:https://blog.51cto.com/fengsonglin/1710274

KVO方式监听数组的变化动态刷新tableView相关推荐

  1. ios 监听数组个数的变化_【iOS】KVO方式监听数组的变化动态刷新tableView

    写作本文来由:   iOS默认不支持对数组的KVO,因为普通方式监听的对象的地址的变化,而数组地址不变,而是里面的值发生了改变 整个过程需要三个步骤 (与普通监听一致) /* *第一步建立观察者及观察 ...

  2. ios 监听数组个数的变化_iOS 监听数组的变化

    这里用的是KVO的方式来实现的, 首先有一个 testArray 这个数组需要监听里面的数据变化 NSMutableArray *testArray; 然后给这个数组注册监听 testArray = ...

  3. Object.defineProperty也能监听数组变化?

    本文简介 点赞 + 关注 + 收藏 = 学会了 首先,解答一下标题:Object.defineProperty 不能监听原生数组的变化.如需监听数组,要将数组转成对象. 在 Vue2 时是使用了 Ob ...

  4. VUE 2 无法监听数组和对象的某些变化

    一.数组 1.  不能监听的情况 (1) 直接通过下标赋值  arr[i] = value (2) 直接修改数组长度 arr.length = newLen 2.  替代做法 (1)修改值 1. Vu ...

  5. web前端面试高频考点——Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)

    系列文章目录 内容 参考链接 Vue基本使用 Vue的基本使用(一文掌握Vue最基础的知识点) Vue通信和高级特性 Vue组件间的通信及高级特性(多种组件间的通信.自定义v-model.nextTi ...

  6. android 获取wifi的加密类型,Android WIFI开发:获取wifi列表,连接指定wifi,获取wifi加密方式,监听wifi网络变化等...

    下面是 Android 开发中 WiFi 的常用配置,如:获取当前 WiFi ,扫描 WiFi 获取列表,连接指定 WiFi ,监听网络变化等等. 下面是效果图: GitHub 下载地址:https: ...

  7. watch深度监听数组_vue watch普通监听和深度监听实例详解(数组和对象)

    vue watch普通监听和深度监听实例详解(数组和对象) 下面通过一段代码给大家介绍vue watch的普通监听和深度监听,具体代码如下所示: var vm=new Vue({ data:{ num ...

  8. MutationObserver 监听DOM树变化

    1 概述 Mutation observer 是用于代替 Mutation events 作为观察DOM树结构发生变化时,做出相应处理的API.为什么要使用mutation observer 去代替 ...

  9. android 监听手机电量变化

    今天,简单讲讲如何监听手机电量的变化. 监听电量是不能静态注册的. 后来上网搜索,发现有五个不能静态注册的广播,这里记录一下,免得下次再后知后觉的发现并惊讶于自己的笨拙. 不能静态注册的广播: and ...

最新文章

  1. 通俗理解 Kubernetes 中的服务,搞懂后真“有趣”
  2. SpringBoot使用AOP
  3. kirin710f是什么处理器_麒麟710a与麒麟710f哪个好?对比区别哪款性能更好一些
  4. [蛋蛋の插画日记]囧...居然漏了一期《可爱100》!
  5. leetcode35 C++ 4ms 搜索插入位置
  6. 使用JUnit 5测试异常
  7. 做小程序的流程总结(基本篇)
  8. mysql无法添加或更新子行_违反完整性约束:1452无法添加或更新子行:
  9. python爬虫下载模块_python爬虫系列(4.5-使用urllib模块方式下载图片)
  10. 给HUSTOJ用户提供的源码阅读与修改建议
  11. HttpURLConnection_Get和Post请求文件上传
  12. Java从零开始学三(public class和class)
  13. pandas根据索引删除dataframe列
  14. Http 请求处理流程[转]
  15. linux gt240驱动下载,支持GT540M NVIDIA新款Linux显卡驱动
  16. 基于STM8S003F3的数字温度计制作
  17. 《供应链管理》—计划的三道防线
  18. 计算机26字母代码表,电脑打字学习:26个汉语拼音字母攻略
  19. js获取当前是第几周
  20. 网易云音乐部门技术面

热门文章

  1. Eclipse的安装与使用
  2. [Eclipse]GEF入门系列(六、添加菜单和工具条)
  3. 信息安全“拷问”智慧城市建设 如何解决
  4. 兼容性—IE6/7下带有overflow:hidden属性的父级元素包不住带有position:relative属性的子元素...
  5. NK3C框架(MyBatis、Durid)连接SQL Server
  6. pageContext.findAttribute()与pageContext.getAttribute()的区别
  7. linux 网络编程之信号机制
  8. 解决'ping' 不是内部或外部命令,也不是可运行的程序
  9. WinAPI: SetWindowPos - 改变窗口的位置与状态
  10. Day2_and_Day3 文件操作