zoukankan      html  css  js  c++  java
  • 【iOS】KVO方式监听数组的变化动态刷新tableView

    原文地址 http://blog.csdn.net/chenglibin1988/article/details/38442307

    !!!!!!model中的数组添加数据时需要注意

    不能这样 [_model.modelArray addObject]方法,需要这样调用   [[_model mutableArrayValueForKey:@"modelArray"] addObject:str];

    !!!!!!

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

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

    /*

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

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

        *  第三步 移除观察者

    */

     

    [objc] view plaincopy
     
    1. 数组不能放在UIViewController里面,在这里面的数组是监听不到数组大小的变化的,需要将需要监听的数组封装到model里面<  

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

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

     

    [objc] view plaincopy
     
    1. @interface model : NSObject  
    2. @property(nonatomic, copy)NSString *name;  
    3. @property(nonatomic, retain)NSMutableArray *modelArray;  

     

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

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

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

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

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

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

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

    [objc] view plaincopy
     
    1. {  
    2.     if ([keyPath isEqualToString:@"modelArray"]) {  
    3.         [_tableView reloadData];  
    4.     }  
    5. }  

        第三步 移除观察者

    [objc] view plaincopy
     
    1. if (_model != nil) {  
    2.     [_model removeObserver:self forKeyPath:@"modelArray"];  
    3. }  


    以下附上本文代码:

    代码中涉及三点

    1 根据数组动态刷新tableview;

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

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

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

    1  NSTimer相关

    [objc] view plaincopy
     
    1. //  
    2. //  NSTimer+DelegateSelf.h  
    3. //  KVOTableview  
    4. //  
    5. //  Created by 程立彬 on 14-8-8.  
    6. //  Copyright (c) 2014年 chenglb. All rights reserved.  
    7. //  
    8.   
    9. //为防止controller和nstimer之间的循环引用,delegate指向当前单例,而不指向controller  
    10.   
    11. #import <Foundation/Foundation.h>  
    12.   
    13. @interface NSTimer (DelegateSelf)  
    14.   
    15. +(NSTimer *)scheduledTimerWithTimeInterval:(int)timeInterval block:(void(^)())block repeats:(BOOL)yesOrNo;  
    16.   
    17. @end  


    [objc] view plaincopy
     
    1. //  
    2. //  NSTimer+DelegateSelf.m  
    3. //  KVOTableview  
    4. //  
    5. //  Created by 程立彬 on 14-8-8.  
    6. //  Copyright (c) 2014年 chenglb. All rights reserved.  
    7. //  
    8.   
    9. #import "NSTimer+DelegateSelf.h"  
    10.   
    11. @implementation NSTimer (DelegateSelf)  
    12.   
    13. +(NSTimer *)scheduledTimerWithTimeInterval:(int)timeInterval block:(void(^)())block repeats:(BOOL)yesOrNo  
    14. {  
    15.     return [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(callBlock:) userInfo:[block copy] repeats:yesOrNo];  
    16. }  
    17.   
    18.   
    19. +(void)callBlock:(NSTimer *)timer  
    20. {  
    21.     void(^block)() = timer.userInfo;  
    22.     if (block != nil) {  
    23.         block();  
    24.     }  
    25. }  
    26.   
    27. @end  


    2 model相关

    [objc] view plaincopy
     
    1. //  
    2. //  model.h  
    3. //  KVOTableview  
    4. //  
    5. //  Created by 程立彬 on 14-8-8.  
    6. //  Copyright (c) 2014年 chenglb. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. @interface model : NSObject  
    12. @property(nonatomic, copy)NSString *name;  
    13. @property(nonatomic, retain)NSMutableArray *modelArray;  
    14.   
    15. -(id)initWithDic:(NSDictionary *)dic;  
    16.   
    17. @end  


    [objc] view plaincopy
     
    1. //  
    2. //  model.m  
    3. //  KVOTableview  
    4. //  
    5. //  Created by 程立彬 on 14-8-8.  
    6. //  Copyright (c) 2014年 chenglb. All rights reserved.  
    7. //  
    8.   
    9.   
    10. //KVC的应用  简化冗余代码  
    11. #import "model.h"  
    12.   
    13. @implementation model  
    14.   
    15. -(id)initWithDic:(NSDictionary *)dic  
    16. {  
    17.     self = [super init];  
    18.     if (self) {  
    19.         [self setValuesForKeysWithDictionary:dic];  
    20.     }  
    21.       
    22.     return self;  
    23. }  
    24.   
    25. -(void)setValue:(id)value forUndefinedKey:(NSString *)key  
    26. {  
    27.     NSLog(@"undefine key ---%@",key);  
    28. }  
    29.   
    30. @end  


    3 UIViewController相关

    [objc] view plaincopy
     
      1. //  
      2. //  RootViewController.m  
      3. //  KVOTableview  
      4. //  
      5. //  Created by 程立彬 on 14-8-8.  
      6. //  Copyright (c) 2014年 chenglb. All rights reserved.  
      7. //  
      8.   
      9. /* 
      10.     *  第一步 建立观察者及观察的对象 
      11.     *  第二步 处理key的变化(根据key的变化刷新UI) 
      12.     *  第三步 移除观察者 
      13.   
      14. */  
      15.   
      16. #import "RootViewController.h"  
      17. #import "NSTimer+DelegateSelf.h"  
      18. #import "model.h"  
      19.   
      20. #define TimeInterval 3.0  
      21.   
      22. @interface RootViewController ()<UITableViewDelegate,UITableViewDataSource>  
      23.   
      24. @property(nonatomic, retain)NSTimer *timer;  
      25. @property(nonatomic, retain)UITableView    *tableView;  
      26. @property(nonatomic, retain)model *model;  
      27.   
      28. @end  
      29.   
      30. @implementation RootViewController  
      31.   
      32. - (void)dealloc  
      33. {  
      34.     //第三步  
      35.     if (_model != nil) {  
      36.         [_model removeObserver:self forKeyPath:@"modelArray"];  
      37.     }  
      38.     //停止定时器  
      39.     if (_timer != nil) {  
      40.         [_timer invalidate];  
      41.         _timer = nil;  
      42.     }  
      43. }  
      44.   
      45. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
      46. {  
      47.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
      48.     if (self) {  
      49.   
      50.         NSDictionary *dic = [NSDictionary dictionaryWithObject:[NSMutableArray arrayWithCapacity:0] forKey:@"modelArray"];  
      51.           
      52.         self.model = [[model alloc] initWithDic:dic];  
      53.       
      54.     }  
      55.     return self;  
      56. }  
      57.   
      58. - (void)viewDidLoad  
      59. {  
      60.     [super viewDidLoad];  
      61.       
      62.     //第一步  
      63.     [_model addObserver:self forKeyPath:@"modelArray" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];  
      64.       
      65.     self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];  
      66.     _tableView.delegate        = self;  
      67.     _tableView.dataSource      = self;  
      68.     _tableView.backgroundColor = [UIColor lightGrayColor];  
      69.     [self.view addSubview:_tableView];  
      70.       
      71.     //定时添加数据  
      72.     [self startTimer];  
      73.       
      74. }  
      75.   
      76. //添加定时器  
      77. -(void)startTimer  
      78. {  
      79.     __block RootViewController *bself = self;  
      80.       
      81.     _timer = [NSTimer scheduledTimerWithTimeInterval:TimeInterval block:^{  
      82.           
      83.         [bself changeArray];  
      84.     } repeats:YES];  
      85.   
      86. }  
      87.   
      88. //增加数组中的元素 自动刷新tableview  
      89. -(void)changeArray  
      90. {  
      91.       
      92.     NSString *str = [NSString stringWithFormat:@"%d",arc4random()%100];  
      93.     [[_model mutableArrayValueForKey:@"modelArray"] addObject:str];  
      94.       
      95. }  
      96.   
      97.   
      98. //第二步 处理变化  
      99. -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context  
      100. {  
      101.     if ([keyPath isEqualToString:@"modelArray"]) {  
      102.         [_tableView reloadData];  
      103.     }  
      104. }  
      105.   
      106.   
      107.   
      108.   
      109. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
      110. {  
      111.     return  [_model.modelArray count];  
      112. }  
      113.   
      114. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;  
      115. {  
      116.     static NSString *cellidentifier = @"cellIdentifier";  
      117.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier];  
      118.     if (cell == nil) {  
      119.         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier];  
      120.     }  
      121.       
      122.     cell.textLabel.text = _model.modelArray[indexPath.row];  
      123.     return cell;  
      124. }  
      125.   
      126.   
      127. - (void)didReceiveMemoryWarning  
      128. {  
      129.     [super didReceiveMemoryWarning];  
      130.     // Dispose of any resources that can be recreated.  
      131. }  
      132.   
      133. @end  
  • 相关阅读:
    Method总结
    使用CSS的五种方式
    debug js code
    Overload
    fiddler模拟弱网测试
    POJ 1753 Flip Game (IDA*)
    UVA 11400 Lighting System Design(照明系统设计)(dp)
    UVA 12563 Jin Ge Jin Qu hao(劲歌金曲)(01背包+滚动数组)
    UVA 116 Unidirectional TSP (单向TSP)(dp多段图的最短路)
    UVA 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)
  • 原文地址:https://www.cnblogs.com/lxllanou/p/4901115.html
Copyright © 2011-2022 走看看