iOS: 使用KVO监听控制器中数组的变化
一、介绍:
KVO是一种能动态监听到属性值的改变的方式,使用场景非常广泛,这里我只讲如何监听控制器ViewController中数组的变化。
二、了解:
首先我们应该知道KVO是不能直接监听控制器ViewController数组的变化的,需要将数组定义在模型中,然后控制器ViewController持有模型对象,通过该对象才能监听。
三、步骤:
<1>在控制器ViewController类中定义一个模型类Model,并在该类中声明一个可变的数组属性modelArray并进行懒加载,其实它最终就是作为控制器ViewController的数组使用;
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end /**
* 在控制器新定义一个模型类
*/
@interface Model : NSObject
/**
* 可变的数组
*/
@property (strong,nonatomic)NSMutableArray *modelArray; @end
#import "ViewController.h" @implementation ViewController @end @implementation Model /**
* 懒加载
*/
-(NSMutableArray *)modelArray{
if(!_modelArray){
_modelArray = [NSMutableArray array];
}
return _modelArray;
} @end
<2>在控制器ViewController中持有模型类Model的全局对象;
#import "ViewController.h" @interface ViewController ()
/**
* 持有模型对象
*/
@property (strong,nonatomic)Model *model; @end
<3>用第2步创建的对象注册监听,监听属性就是数组modelArray,即modelArray作为keyPath值,注册方法为;
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
//注册KVO监听
[_model addObserver:self forKeyPath:@"modelArray" options:NSKeyValueObservingOptionNew context:nil];
<4>重写监听方法,监听值的变化;
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context;
//重写监听方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"modelArray"]) {
NSLog(@"%ld",_model.modelArray.count);
}
}
<5>移除监听,最后释放内内存时需要把监听移除掉
-(void)dealloc{
[_model removeObserver:self forKeyPath:@"modelArray"];
}
<6>点击界面,模拟数据添加到数组中,添加方法必须是:- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSObject *obj = [[NSObject alloc]init];
[[_model mutableArrayValueForKeyPath:@"modelArray"] addObject:obj];
}
四、演示截图:(每点击一次,能够监听到数组个数增加1)
五、完整代码如下:
.h文件
//
// ViewController.h
// KVOTest
//
// Created by 夏远全 on 16/11/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end /**
* 在控制器新定义一个模型类
*/
@interface Model : NSObject
/**
* 可变的数组
*/
@property (strong,nonatomic)NSMutableArray *modelArray; @end
.m文件
//
// ViewController.m
// KVOTest
//
// Created by 夏远全 on 16/11/23.
// Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.
// #import "ViewController.h" @interface ViewController ()
/**
* 持有模型对象
*/
@property (strong,nonatomic)Model *model; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //1.创建模型对象
_model = [[Model alloc]init]; //2.注册KVO监听
[_model addObserver:self forKeyPath:@"modelArray" options:NSKeyValueObservingOptionNew context:nil];
} /**
* 3.重写监听方法
*/
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"modelArray"]) { NSLog(@"%ld",_model.modelArray.count);
}
} /**
* 4.移除监听
*/ -(void)dealloc{
[_model removeObserver:self forKeyPath:@"modelArray"];
} /**
* 5.模拟往数组添加数据
*/
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSObject *obj = [[NSObject alloc]init];
[[_model mutableArrayValueForKeyPath:@"modelArray"] addObject:obj];
} @end @implementation Model /**
* 懒加载
*/
-(NSMutableArray *)modelArray{
if(!_modelArray){
_modelArray = [NSMutableArray array];
}
return _modelArray;
} @end
注明:本人原创,牛人可以路过,希望可以帮到小白,嘿嘿
iOS: 使用KVO监听控制器中数组的变化的更多相关文章
- 黎活明8天快速掌握android视频教程--21_监听ContentProvider中数据的变化
采用ContentProvider除了可以让其他应用访问当前的app的数据之外,还有可以实现当app的数据发送变化的时候,通知注册了数据变化通知的调用者 其他所有的代码都和第20讲的一样,不同的地方看 ...
- 监听localStorage中的数据变化
问题描述:我们在js里面获取了某一个localstorage的值,但是后期它可能改变了,我们js只执行一遍没办法再次获取它的值,当然可以刷新页面获取,但如果是我们的但页面就不能刷新页面了,此时:我们可 ...
- js实时监听input中值的变化
$(function(){ $('#inputid').bind('input propertychange', function() { // input 中的值 var params = $(th ...
- 在vue中使用watch监听对象或数组
最近发现在vue中使用watch监听对象或者数组时,当数组或者对象只是单一的值改变时,并不会出发watch中的事件. 在找问题过程中,发现当数组使用push一类的方法时,会触发watch,如果只是单一 ...
- js 实时监听input中值变化
注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...
- iOS地图 -- 区域监听的实现和小练习
区域监听用到的方法 [self.mgr startMonitoringForRegion:region]; --> 开启区域监听,没有返回值,在代理方法中得到信息并且处理信息 注:该方法只有用户 ...
- 移动端(IOS)iframe监听不到 onscroll 事件
问题描述: 我在一个页面A中有瀑布流,点击瀑布流中的图片需要进入到另外一个页面B,点击返回需要回到页面A中点击的位置,为了实现该效果所以在页面A中嵌入iframe,iframe指向页面B,页面B中同样 ...
- oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接
oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接 oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接 or ...
- Fragment-如何监听fragment中的回退事件与怎样保存fragment状态
一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退 ...
随机推荐
- SQL中distinct的用法(转自博主:Rain Man)
在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值.关键词 distinct用于返回唯一不同的值. 表A: 示例1 select distinct nam ...
- QPushButton 与 QListWidget 的按键响应
在Qt中添加按钮或表格控件时需要添加其按键响应,一般来说有两种方法,一种是直接实现其响应函数,第二种是自己写一个响应函数,然后用Qt的信号槽将它们连接起来.愚以为第一种方法更为简单一些. 声明这些控件 ...
- 从prompt输入10个人的年龄放入数组,将十个人的年龄求总和。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- php 获取当前脚本的url的案例
关于用php 获取当前脚本的url很多朋友会说很简单,但是要获取很详细的就要经过多次判断. $PHP_TIME = time();$PHP_SELF = isset($_SERVER['PHP_SEL ...
- Leetcode | Minimum/Maximum Depth of Binary Tree
Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum depth is the n ...
- metasploit-post模块信息
Name Disclosure Date Rank Description ---- ...
- PHP 对象和引用总结
PHP 中使用 简单变量 和 对象 时的区别: ① 很多数据类型都可以写时复制(copy-on-write),例: <?php $a = 'test1'; $b = $a; $b = 'test ...
- 利用SpannableString设置文本
private void setTips(){ String big = "大字深色"; String small = "小字淡色"; Spannable ti ...
- swift 子类继承父类
// 子类的指定构造方法必须调用父类构造方法,并确保调用发生在子类存储属性初始化之后.而且指定构造方法不能调用同一个类中的其他指定构造方法: // 便利构造方法必须调用同一个类中的其他指定构造方法(可 ...
- LR处理文件上传和下载
文件上传 在业务场景有上传操作时,使用LR能录制到上传操作,代码如下.在录制的原始代码中,Filename的Value是上传的文件名,name的Value是一串文件名的加密串,file的Value也是 ...
采用ContentProvider除了可以让其他应用访问当前的app的数据之外,还有可以实现当app的数据发送变化的时候,通知注册了数据变化通知的调用者 其他所有的代码都和第20讲的一样,不同的地方看 ...
问题描述:我们在js里面获取了某一个localstorage的值,但是后期它可能改变了,我们js只执行一遍没办法再次获取它的值,当然可以刷新页面获取,但如果是我们的但页面就不能刷新页面了,此时:我们可 ...
$(function(){ $('#inputid').bind('input propertychange', function() { // input 中的值 var params = $(th ...
最近发现在vue中使用watch监听对象或者数组时,当数组或者对象只是单一的值改变时,并不会出发watch中的事件. 在找问题过程中,发现当数组使用push一类的方法时,会触发watch,如果只是单一 ...
注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...
区域监听用到的方法 [self.mgr startMonitoringForRegion:region]; --> 开启区域监听,没有返回值,在代理方法中得到信息并且处理信息 注:该方法只有用户 ...
问题描述: 我在一个页面A中有瀑布流,点击瀑布流中的图片需要进入到另外一个页面B,点击返回需要回到页面A中点击的位置,为了实现该效果所以在页面A中嵌入iframe,iframe指向页面B,页面B中同样 ...
oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接 oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接 or ...
一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退 ...
在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值.关键词 distinct用于返回唯一不同的值. 表A: 示例1 select distinct nam ...
在Qt中添加按钮或表格控件时需要添加其按键响应,一般来说有两种方法,一种是直接实现其响应函数,第二种是自己写一个响应函数,然后用Qt的信号槽将它们连接起来.愚以为第一种方法更为简单一些. 声明这些控件 ...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
关于用php 获取当前脚本的url很多朋友会说很简单,但是要获取很详细的就要经过多次判断. $PHP_TIME = time();$PHP_SELF = isset($_SERVER['PHP_SEL ...
Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum depth is the n ...
Name Disclosure Date Rank Description ---- ...
PHP 中使用 简单变量 和 对象 时的区别: ① 很多数据类型都可以写时复制(copy-on-write),例: <?php $a = 'test1'; $b = $a; $b = 'test ...
private void setTips(){ String big = "大字深色"; String small = "小字淡色"; Spannable ti ...
// 子类的指定构造方法必须调用父类构造方法,并确保调用发生在子类存储属性初始化之后.而且指定构造方法不能调用同一个类中的其他指定构造方法: // 便利构造方法必须调用同一个类中的其他指定构造方法(可 ...
文件上传 在业务场景有上传操作时,使用LR能录制到上传操作,代码如下.在录制的原始代码中,Filename的Value是上传的文件名,name的Value是一串文件名的加密串,file的Value也是 ...