【iOS】KVO方式监听数组的变化动态刷新tableView
来源:互联网 发布:跳水 违反 知乎 编辑:程序博客网 时间:2024/06/06 09:09
写作本文来由: iOS默认不支持对数组的KVO,因为普通方式监听的对象的地址的变化,而数组地址不变,而是里面的值发生了改变
整个过程需要三个步骤 (与普通监听一致)
/*
* 第一步 建立观察者及观察的对象
* 第二步 处理key的变化(根据key的变化刷新UI)
* 第三步 移除观察者
*/
数组不能放在UIViewController里面,在这里面的数组是监听不到数组大小的变化的,需要将需要监听的数组封装到model里面<
model类为: 将监听的数组封装到model里,不能监听UIViewController里面的数组
两个属性 一个 字符串类的姓名,一个数组类的modelArray,我们需要的就是监听modelArray里面元素的变化
@interface model : NSObject@property(nonatomic, copy)NSString *name;@property(nonatomic, retain)NSMutableArray *modelArray;
第一步 建立观察者及观察的对象
[_modeladdObserver:selfforKeyPath:@"modelArray"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:NULL];
第二步 处理key的变化(根据key的变化刷新UI)
最重要的就是添加数据这里
不能这样 [_model.modelArray addObject]方法,需要这样调用 [[_model mutableArrayValueForKey:@"modelArray"] addObject:str];原因稍后说明。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{ if ([keyPath isEqualToString:@"modelArray"]) { [_tableView reloadData]; }}
if (_model != nil) { [_model removeObserver:self forKeyPath:@"modelArray"]; }
以下附上本文代码:
代码中涉及三点
1 根据数组动态刷新tableview;
2 定时器的使用(涉及循环引用问题);
3 使用KVC优化model的初始化代码。
没找到上传整个工程的方法,暂时附上代码
1 NSTimer相关
//// 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
//// 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相关
//// 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
//// 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相关
//// 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:(void *)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
3 0
- 【iOS】KVO方式监听数组的变化动态刷新tableView
- iOS: 使用KVO监听控制器中数组的变化
- KVC 和 KVO 监听容器类(数组等)的变化
- 利用KVO监听属性值的变化
- iOS动态监听网络变化
- 小胖说事48-----iOS 文本框变化 监听的3种方式
- ios 文本框变化 监听的3种方式
- [iOS KVO监控view的frame变化]
- iOS tableView的刷新 笔记
- IOS的KVO不能监听的场景
- iOS中键值监听KVO的学习
- ios kvo 监听值遇到的问题
- iOS KVO监听
- KVO监听UI控件的frame变化,kVO的简单使用,KVC的初步了解
- IPHONE 和 KVC/KVO 监听对象属性变化(例如:获取textView 的text的变化)
- IPHONE 和 KVC/KVO 监听对象属性变化(例如:获取textView 的text的变化)
- tableview 高度适配内容(高度随着cell行数变化而动态变化)及(监听contentsize变化)
- iOS—TableView的点击监听和数据刷新(Alert的多种样式) -tag传值的技巧
- 润乾——动态宏
- ucGUI 消息驱动机制结构和使用
- 浅析PHP编程中10个最常见的错误
- hdu3723+Catalan数
- webservice1 tule
- 【iOS】KVO方式监听数组的变化动态刷新tableView
- printf返回值是什么?
- invoke fabic with python
- oracle初始密码
- APUE第4章 文件和目录笔记
- UVA 11255 - Necklace(Ploya)
- Eclipse怎样设置拼写检查
- 1.5.2.2 到稳健结束
- Eclipse add Tomcat server【无法输入server name】