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
时间: 2024-11-06 02:09:44

iOS: 使用KVO监听控制器中数组的变化的相关文章

实时监听组件中路由的变化

实时监听组件中路由的变化,通过watch来进行监听,当路由发生变化时,重新赋值,重新执行从后台获取数据的操作 watch: { '$route' (to, from) { this.listQuery.keywords=this.$route.query.keywords this.searchByKeywords() } }, methods: { searchByKeywords() { this.$store.dispatch('updateLoading', true) fetchSea

js实时监听input中值的变化

$(function(){ $('#inputid').bind('input propertychange', function() { // input 中的值 var params = $(this).val(); }); }) 类似于实现‘还能输入xxx个字符’的效果. oninput, onpropertychange, onchange的用法: 1.onchange 触发事件必须满足两个条件: a)当前对象属性改变,并且是由键盘或鼠标事件激发的(脚本触发无效) b)当前对象失去焦点(

KVO监听

Main.m #import "Children.h" #import "Nurse.h" int main(int argc, const char * argv[]) { Children *children = [[Children alloc] init]; Nurse *nurse = [[Nurse alloc] initWithChildren:children]; [[NSRunLoop currentRunLoop] run]; [children

ios ---键盘的监听事件

//在view将要出现的时候重载viewWillAppear方法添加通知 监听事件 keyboardWillShow:  keyboardWillHide: - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:

CC1101 监听空气中载波信号强度(CCA)功能调试通过

阅读本文章前,请先认真阅读数据手册,同时查看我转载的CCA(1)和CCA(2)两篇文章进行扫盲. 最近一直在用CC1101这款无线芯片,今天把CCA功能调试成功了,特来分享一下.我的思路是使能CC1101为CCA功能,GDO2引脚配置为输出载波感应电平,设置好感应电平阈值.现在监听空气中的载波信号强度,如果接收信号强度高于门限时,GDO2为高电平:当接收信号强度低于门限时,GDO2为低电平. CCA初始化函数如下: void  CC1101CCA( void )//配置为载波监听功能 { CC1

使用Log4jdbc-log4j2监听MyBatis中运行的SQL和Connection

引言: 在项目中使用了MyBatis,一个比较苦恼的问题是无法看到执行的SQL的具体情况,所以,就找到了Log4jdbc-log4j2.这个是一个基于jdbc层面的监听工具,可以监听对于数据库的主要操作,从而完美的查看到其中执行的操作. 1. Log4jdbc-log4j2版本选择 log4jdbc-log4j2-jdbc3.jar for JDBC 3 support in JDK 1.5 log4jdbc-log4j2-jdbc4.jar for JDBC 4 support in JDK

js 实时监听input中值变化

js 实时监听input中值变化 分类: Javascript2014-05-11 11:13 849人阅读 评论(0) 收藏 举报 [html] view plaincopyprint? <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>RunJS

Android 监听 Android中监听系统网络连接打开或者关闭的实现代码

本篇文章对Android中监听系统网络连接打开或者关闭的实现用实例进行了介绍.需要的朋友参考下 很简单,所以直接看代码 复制代码 代码如下: package xxx; import android.content.BroadcastReceiver;  import android.content.Context;  import android.content.Intent;  import android.net.ConnectivityManager;  import android.ne

Fragment-如何监听fragment中的回退事件与怎样保存fragment状态

一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退事件时,想当然的也想着重写onBackPressed()方法,这时候你会发现:Fragment中根本就没有onBackPressed()方法给你重写.这可怎么破! 想想,在前面的例子中,我们在Activity的一个fragment_container里依次Add进fragment1,fragment