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中的回退 ...
随机推荐
- 五、Pillar数据管理中心
Pillar是数据管理中心. Pillar在saltstack中主要作用是存储和定义一些配置管理中需要的信息(比如:软件版本,用户名,密码等) 修改pillar相关配置文件: [root@super6 ...
- [转] - linux下使用write\send发送数据报 EAGAIN : Resource temporarily unavailable 错
linux下使用write\send发送数据报 EAGAIN : Resource temporarily unavailable 错 首先是我把套接字设置为异步的了,然后在使用write发送数据时采 ...
- HTML: margin重疊現象的說明
2句話: ①相鄰的兩個普通元素,上下邊距,不是簡單的相加,而是取邊距較大的元素(若相邻的两个普通兄弟元素,它们的margin 值是一样的,则各取两个元素的margin 值的一半.)②关系为父子的两个d ...
- [转]LaTeX处女级入门命令语法集
1.LaTeX文件的框架如下: \documentclass{article} \begin{document} This is the body of the article \end{docume ...
- 5 个 Composer 小技巧
Composer是新一代的PHP依赖管理工具.其介绍和基本用法可以看这篇<Composer PHP依赖管理的新时代>.本文介绍使用Composer的五个小技巧,希望能给你的PHP开发带来方 ...
- faker image
$faker->image http://placehold.it http://placekitten.com/g/200/300 带文字 https://placeholdit.imgix. ...
- Delphi 记录类型- 结构指针
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- java override
java override // 覆盖父类的方法,在子类直接调用子类内部这个方法时 public class TestCalc{ protected static class Wine{ String ...
- X Window 程式设计
X Window 程式设计 转 http://www.cppblog.com/zmj/archive/2007/05/18/24331.html X Window 程式设计 X Window 程式 ...
- (转)js一道比较考验的题目
转载下别人曾经出过的一道面试题,此题是他出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多难只是因为大多面试者 ...
采用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中的回退 ...
Pillar是数据管理中心. Pillar在saltstack中主要作用是存储和定义一些配置管理中需要的信息(比如:软件版本,用户名,密码等) 修改pillar相关配置文件: [root@super6 ...
linux下使用write\send发送数据报 EAGAIN : Resource temporarily unavailable 错 首先是我把套接字设置为异步的了,然后在使用write发送数据时采 ...
2句話: ①相鄰的兩個普通元素,上下邊距,不是簡單的相加,而是取邊距較大的元素(若相邻的两个普通兄弟元素,它们的margin 值是一样的,则各取两个元素的margin 值的一半.)②关系为父子的两个d ...
1.LaTeX文件的框架如下: \documentclass{article} \begin{document} This is the body of the article \end{docume ...
Composer是新一代的PHP依赖管理工具.其介绍和基本用法可以看这篇<Composer PHP依赖管理的新时代>.本文介绍使用Composer的五个小技巧,希望能给你的PHP开发带来方 ...
$faker->image http://placehold.it http://placekitten.com/g/200/300 带文字 https://placeholdit.imgix. ...
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
java override // 覆盖父类的方法,在子类直接调用子类内部这个方法时 public class TestCalc{ protected static class Wine{ String ...
X Window 程式设计 转 http://www.cppblog.com/zmj/archive/2007/05/18/24331.html X Window 程式设计 X Window 程式 ...
转载下别人曾经出过的一道面试题,此题是他出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多难只是因为大多面试者 ...