iOS中KVC与KVO的应用解析

简介: iOS中KVC与KVO的应用解析

iOS中KVC与KVO的应用解析


一、NSKeyValueCoding(KVC)


1、从一个小例子引入


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


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


//.h文件

#import <Foundation/Foundation.h>

@interface Model : NSObject

{

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

   NSString * str;

}

@end

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


   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类中有一个字符串,我们可以通过如下的方式赋值取值


//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:参数传递


监听的选项枚举如下:


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是传递的参数。


代码示例:


- (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);

   }

}

目录
相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1385 4
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
11月前
|
iOS开发 开发者 Windows
uniapp云打包ios应用证书的获取方法,生成指南
打包用到的一共两个文件,一个是p12格式的私钥证书,一个是证书profile文件。其中生成p12证书的时候,按照官网的教程,是需要MAC电脑来协助做的,主要是生成一些csr文件和导出p12证书等。其实这些步骤也可以借助一些其他的工具来实现,不一定使用mac电脑,用windows电脑也可以创建。
1322 0
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
存储 安全 数据安全/隐私保护
深入解析iOS 14隐私保护功能:用户数据安全的新里程碑
随着数字时代的到来,个人隐私保护成为全球关注的焦点。苹果公司在最新的iOS 14系统中引入了一系列创新的隐私保护功能,旨在为用户提供更透明的数据使用信息和更强的控制权。本文将深入探讨iOS 14中的几项关键隐私功能,包括App跟踪透明性、简化的隐私设置以及增强的系统安全性,分析它们如何共同作用以提升用户的隐私保护水平。
798 3
|
数据安全/隐私保护 iOS开发 开发者
iOS 14隐私保护新特性深度解析####
随着数字时代的到来,隐私保护已成为全球用户最为关注的问题之一。苹果在最新的iOS 14系统中引入了一系列创新功能,旨在增强用户的隐私和数据安全。本文将深入探讨iOS 14中的几大隐私保护新特性,包括App跟踪透明度、剪贴板访问通知和智能防追踪功能,分析这些功能如何提升用户隐私保护,并评估它们对开发者和用户体验的影响。 ####
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
11月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1098 29
|
11月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
467 4
|
11月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
  • DNS