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中的回退 ...
随机推荐
- [转]如何:定义和处理 SOAP 标头
本文转自:http://msdn.microsoft.com/zh-cn/library/vstudio/8728chd5(v=vs.100).aspx 本主题专门介绍一项旧有技术.现在应通过使用以下 ...
- 在Windows上启用LDAPs
公司的环境比较特殊, Windows server + Linux desktop, 所以我们希望在server端启用LDAP over SSL功能. 当中走了不少弯路, 网上文章也搜了一大堆, 千辛 ...
- 字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)
(关于字符编码的深入解释,请参见我的原创文章<关于字符编码,你所需要知道的>.) 此文为转载,有少许修订,原文出处不详. 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同 ...
- metasploit--exploit模块信息
Name Disclosure Date Rank Description ---- ...
- 状态模式 java && php
状态模式 java && php 状态模式 输入信号是事件:输出是状态结果,状态模式状态机就是一个黑盒子.状态模式主要突出了两个字:”改变”,对象的状态决定了状态的行为,事物的 ...
- wordpress 常用函数 checked(),selected(),disabled()
checked().selected().disabled(),这三个函数是主题设计和插件设计中添加后台设置比较常用到的函数. 例如自定义一个widget,这个widget有一个字段为文章排列方式.文 ...
- nginx日志配置[转]
* * * sh /home/zyf/sh/cut_nginx_log.sh 这样就每天的0点1分把nginx日志重命名为日期格式,并重新生成今天的新日志文件。 日志对于统计排错来说非常有利的。本文 ...
- Locking
Computer Science An Overview _J. Glenn Brookshear _11th Edition To solve such problems, a DBMS could ...
- Delphi下使用MapWinGIS控件打开GIS图层
unit Unit3; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- java 重写 重载
首先我们来讲讲:重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态 ...
采用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中的回退 ...
本文转自:http://msdn.microsoft.com/zh-cn/library/vstudio/8728chd5(v=vs.100).aspx 本主题专门介绍一项旧有技术.现在应通过使用以下 ...
公司的环境比较特殊, Windows server + Linux desktop, 所以我们希望在server端启用LDAP over SSL功能. 当中走了不少弯路, 网上文章也搜了一大堆, 千辛 ...
(关于字符编码的深入解释,请参见我的原创文章<关于字符编码,你所需要知道的>.) 此文为转载,有少许修订,原文出处不详. 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同 ...
Name Disclosure Date Rank Description ---- ...
状态模式 java && php 状态模式 输入信号是事件:输出是状态结果,状态模式状态机就是一个黑盒子.状态模式主要突出了两个字:”改变”,对象的状态决定了状态的行为,事物的 ...
checked().selected().disabled(),这三个函数是主题设计和插件设计中添加后台设置比较常用到的函数. 例如自定义一个widget,这个widget有一个字段为文章排列方式.文 ...
* * * sh /home/zyf/sh/cut_nginx_log.sh 这样就每天的0点1分把nginx日志重命名为日期格式,并重新生成今天的新日志文件。 日志对于统计排错来说非常有利的。本文 ...
Computer Science An Overview _J. Glenn Brookshear _11th Edition To solve such problems, a DBMS could ...
unit Unit3; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
首先我们来讲讲:重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态 ...