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中的回退 ...
随机推荐
- iOS真机调试的验证项
基本的匹配项 App 描述文件 BundleID (匹配) ApplicationID Cert (匹配) Cert DeviceID (被包含) DeviceIDs 描述文件就是包含了各种需要验证信 ...
- WPF 增加合计一栏
占坑中 先抛个参考链接 http://stackoverflow.com/questions/678690/how-can-i-create-a-group-footer-in-a-wpf-list ...
- 连连看beta发布
组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 代码地址:HTTPS:https://git.coding.net/jx8zjs/llk.git SSH:git@git.coding.n ...
- Asp.Net:Repeater 详情 备用
页面 repeator就想for循环一样,没有编辑模板,有删除delete和详情detail模板 <%@ Page Language="C#" AutoEventWireup ...
- 块级&行内(内联)元素
行内元素列表 <a>标签可定义锚 <abbr>表示一个缩写形式 <acronym>定义只取首字母缩写 <b>字体加粗 <bdo>可覆盖默认的 ...
- OpenGL extension specification (from openGL.org)
Shader read/write/atomic into UAV global memory (need manual sync) http://www.opengl.org/registry/sp ...
- twitter storm源码走读之6 -- Trident Topology执行过程分析
欢迎转载,转载请注明出处,徽沪一郎. TridentTopology是storm提供的高层使用接口,常见的一些SQL中的操作在tridenttopology提供的api中都有类似的影射.关于Tride ...
- 每天学点GDB14
在上一篇文章中讲到了ptrace,那么我们完全可以用ptrace来写一个非常简单的trace工具,用以trace程序的具体运行过程. 用它可以很清楚的回答,使用glibc编译后的hello world ...
- 使用VirtualEnvWrapper隔离python项目的库依赖
是什么 VirtualEnv用于在一台机器上创建多个独立的python运行环境,VirtualEnvWrapper为前者提供了一些便利的命令行上的封装. 为什么要用 - 隔离项目之间的第三方包依赖,如 ...
- [转]常用 Git 命令清单
作者: 阮一峰 我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专 ...
采用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中的回退 ...
基本的匹配项 App 描述文件 BundleID (匹配) ApplicationID Cert (匹配) Cert DeviceID (被包含) DeviceIDs 描述文件就是包含了各种需要验证信 ...
占坑中 先抛个参考链接 http://stackoverflow.com/questions/678690/how-can-i-create-a-group-footer-in-a-wpf-list ...
组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 代码地址:HTTPS:https://git.coding.net/jx8zjs/llk.git SSH:git@git.coding.n ...
页面 repeator就想for循环一样,没有编辑模板,有删除delete和详情detail模板 <%@ Page Language="C#" AutoEventWireup ...
行内元素列表 <a>标签可定义锚 <abbr>表示一个缩写形式 <acronym>定义只取首字母缩写 <b>字体加粗 <bdo>可覆盖默认的 ...
Shader read/write/atomic into UAV global memory (need manual sync) http://www.opengl.org/registry/sp ...
欢迎转载,转载请注明出处,徽沪一郎. TridentTopology是storm提供的高层使用接口,常见的一些SQL中的操作在tridenttopology提供的api中都有类似的影射.关于Tride ...
在上一篇文章中讲到了ptrace,那么我们完全可以用ptrace来写一个非常简单的trace工具,用以trace程序的具体运行过程. 用它可以很清楚的回答,使用glibc编译后的hello world ...
是什么 VirtualEnv用于在一台机器上创建多个独立的python运行环境,VirtualEnvWrapper为前者提供了一些便利的命令行上的封装. 为什么要用 - 隔离项目之间的第三方包依赖,如 ...
作者: 阮一峰 我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专 ...