IOS中KVC与KVO的应用解析

IOS中KVC与KVO的应用解析

一、NSKeyValueCoding(KVC)

1、从一个小例子引入

KVC键值编码是Object-C为我们提供的一种对成员变量赋值的方法。在探讨其方法之前,我们先来看一个小例子:

首先,创建一个数据模型model类:

?


1

2

3

4

5

6

7

8

//.h文件

#import <Foundation/Foundation.h>

@interface Model : NSObject

{

    @public//将成员变量设置为公有的 以便其他文件有访问权限

    NSString * str;

}

@end

我们在其他文件中有两种方法str进行赋值和取值:

?


1

2

3

4

5

    Model * model = [[Model alloc]init];

    model->str=@"312";//普通方法赋值

    [model setValue:@"321" forKey:@"str"];//kvc赋值

    NSLog(@"%@",model->str);//普通方法取值

    NSLog(@"%@",[model valueForKey:@"str"]);//kvc取值

同样的,对于用@property声明的变量,使用kvc的效果和使用点语法,setter,getter方法的效果是一样的。

2、KVC有关函数方法详解

通过上面的例子,我们已经可以简单了解KVC是干什么的了,下面是一些常用方法。

+ (BOOL)accessInstanceVariablesDirectly;

这个方法类似一个开关,默认返回为YES,表示支持KVC方式赋值,也可以在子类中将其重写,如果返回为NO,则再进行KVC会抛出异常。

- (id)valueForKey:(NSString *)key;

通过键取值

- (void)setValue:(id)value forKey:(NSString *)key;

通过字符串键给成员变量赋值

- (BOOL)validateValue:(inout id *)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;

系统默认实现的方法,验证一个键值是否有效

- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;

将取到的值放入一个可变数组中

- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);

将取到的值放入可变的有序集合中

- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;

将取到的值放入可变的集合中

- (id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

上面这两个方法分别是通过路径赋值与取值,数据结构类似地图,比如在model类中有一个成员变量model2,在Model2类中有一个字符串,我们可以通过如下的方式赋值取值

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

//Model.h

#import "Model2.h"

@interface Model : NSObject

{

    @public

    NSString * str;

    Model2 * model2;

}

//Model2.h

@interface Model2 : NSObject

{

@public

    NSString * str2;

}

@end

//其他文件

    Model * model = [[Model alloc]init];

    Model2 * model2 = [[Model2 alloc]init];

    model->model2=model2;

    [model setValue:@"123" forKeyPath:@"model2.str2"];

    NSLog(@"%@",[model valueForKeyPath:@"model2.str2"]);

- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;

上面三个方法与前面类似,只是是从路径取值的。

- (id)valueForUndefinedKey:(NSString *)key;

这个方法可以获取没有提前定义的成员变量的值,比如运行时创建的,下面这个方法是给未定义的成员变量赋值

- (void)setValue:(id)value forUndefinedKey:(NSString *)key;

注意:这两个方法默认的实现会抛出异常,子类必须重写才能使用。

- (void)setNilValueForKey:(NSString *)key;

将成员变量置为nil

- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;

根据键值获取键值对字典

- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

通过字典对成员变量同意赋值,经常使用

二、NSKeyValueObservingCustomization(KVO)

KVO是一种消息监听机制,可以在某个量发生变化的时候将消息传送给监听者,因此广泛用于传值,界面低耦合等逻辑中。KVO机制的核心是以下三个方法:

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

使用这个方法注册一个监听者,参数解释如下:

observer:监听者对象

keyPath:监听的参数

options:监听选项

context:参数传递

监听的选项枚举如下:

?


1

2

3

4

5

6

7

8

typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {

    NSKeyValueObservingOptionNew = 0x01,//回调的字典中存放新值

    NSKeyValueObservingOptionOld = 0x02,//回调的字典中存放旧值

    NSKeyValueObservingOptionInitial ,//值改变前进行回调

    NSKeyValueObservingOptionPrior//改变前后都进行回调

 

};

//回调字典后面会解释

- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context ;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

这两个方法都是用来移除监听者

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

这个方法是监听对象数据改变时回调的方法,change是一个字典,字典中根据监听的选项不同,存放不同的值(新或者旧)。context是传递的参数。

代码示例:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

     model = [[Model alloc]init];

    //添加监听者

    [model addObserver:self forKeyPath:@"str" options:NSKeyValueObservingOptionNew context:@"321"];

    [model setValue:@"qw" forKey:@"str"];

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    if ([keyPath isEqualToString:@"str"]) {

        NSLog(@"%@",context);

    }

}

时间: 2024-10-29 22:24:27

IOS中KVC与KVO的应用解析的相关文章

IOS之KVC和KVO(未完待续)

KVC和KVO KVC : Key value Coding 作用: 1.kVC可以给对象的私有变量赋值 2.用于字典转模型(到后面用MJExtension) 3.通过KVC取出私有变量值 4.模型对象转字典(了解) 利用KVC赋值: 利用KVC取值 使用注意: 1.设置key/keyPath位置的字符串必须保证有对应的属性(或者_属性) 否则会报错 2.字典转模型的使用注意: 2-1.必须保证字典中对应key在模型中能找到对应的属性 2-2.模型中的属性可以在字典中没有对应的Key setVa

iOS中Block的回调使用和解析详解_IOS

Block 回调实现 先跟着我实现最简单的 Block 回调传参的使用,如果你能举一反三,基本上可以满足了 OC 中的开发需求.已经实现的同学可以跳到下一节. 首先解释一下我们例子要实现什么功能(其实是烂大街又最形象的例子): 有两个视图控制器 A 和 B,现在点击 A 上的按钮跳转到视图 B ,并在 B 中的textfield 输入字符串,点击 B 中的跳转按钮跳转回 A ,并将之前输入的字符串 显示在 A 中的 label 上.也就是说 A 视图中需要回调 B 视图中的数据. 想不明白的同学

iOS开发系列--Objective-C之KVC、KVO

概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听(KVO)特性: 键值编码KVC 键值监听KVO 键值编码KVC 我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Value Codin

IOS中JSON数据的解析

IOS中JSON数据解析 官方为我们提供的解析JSON数据的类是NSJSONSerialization,首先我们先来看下这个类的几个方法: + (BOOL)isValidJSONObject:(id)obj; 判断一个数据对象是否可以转化为JSON数据 + (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error; 将JSON数据写为NSData数据,其中opt参数

IOS中Json解析实例方法详解(四种方法)_IOS

作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此"http://www.bejson.com/"网站来进行JSON格式化校验(点击打开链接).此网站不仅可以检测Json代码中的错误,而且可以以视图形式显示json中的数据内容,很是方便. 从IOS5开始,APPLE提供了对json的原生支持(NSJSONSerialization),但是为了兼容以前的iOS版本,可以使用第三方库来解析Json. 本文将介绍Tou

iOS中线程Call Stack的捕获和解析(二)

上接iOS中线程Call Stack的捕获和解析(一). 1. 部分参考资料 做这一块时也是查阅了很多链接和书籍,包括但不限于: <OS X ABI Mach-O File Format Reference> <Mach-O Programming Topics> <程序员的自我修养>--这本几年前读过的,又一次从书架上拿下来温习,主要是用来对比确认: <The Mac Hacker's Handbook> <Mac OS X and iOS Inte

iOS中线程Call Stack的捕获和解析(一)

http://blog.csdn.net/jasonblog/article/details/49909209这里对上个月做的一个技术项目做部分技术小结,这篇文章描述的功能和我们在使用Xcode进行调试时点击暂停的效果类似. 一.获取任意一个线程的Call Stack 如果要获取当前线程的调用栈,可以直接使用现有API:[NSThread callStackSymbols]. 但是并没有相关API支持获取任意线程的调用栈,所以只能自己编码实现. 1. 基础结构 一个线程的调用栈是什么样的呢? 我

菜鸟-解析IOS中plist. 不会解析

问题描述 解析IOS中plist. 不会解析 不知道里面的字典字符串的解析,不知道怎么去运用,希望给举个例子,麻烦了 解决方案 Plist/NSUserDefault解析 解决方案二: http://zhidao.baidu.com/link?url=I2rwg6oQShDFbdmOOATQTGCOOokiq-1qrlUGp9zM2PxWbXresLOs8Ed6O9Hqq0VQqx4goTczgH7SmOnusFXPhq

全面解析iOS中同步请求、异步请求、GET请求、POST请求_IOS

先给大家分别介绍下iOS中同步请求.异步请求.GET请求.POST所代表的意思,然后在逐一通过实例给大家介绍. 1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然可以对UI进行操作,程序可以继续运行 3.GET请求,将参数直接写在访问路径上.操作简单,不过容易被外界看到,安全性不高,地址最多255字节: 4.POST请求,将参数放到body里面.P