RAC学习笔记之一:KVC(一)html
原帖收藏于IT老兵博客。ios
学习RAC,须要先去了解KVC和KVO,这里对KVC进行一下总结。web
参考苹果官网的介绍编程
You typically use accessor methods to gain access to an object’s properties. A get accessor (or getter) returns the value of a property. A set accessor (or setter) sets the value of a property. In Objective-C, you can also directly access a property’s underlying instance variable. Accessing an object property in any of these ways is straightforward, but requires calling on a property-specific method or variable name. As the list of properties grows or changes, so also must the code which accesses these properties. In contrast, a key-value coding compliant object provides a simple messaging interface that is consistent across all of its properties.
Key-value coding is a fundamental concept that underlies many other Cocoa technologies, such as key-value observing, Cocoa bindings, Core Data, and AppleScript-ability. Key-value coding can also help to simplify your code in some cases.app
一言以蔽之,这一段的意思是编写传统的获取和设置属性的方法(getter和setter)会随着属性值的增长而变得愈来愈枯燥,因此OC提供了一种直接根据属性名设置值的方法,这种方法就叫作KVC,Key-value coding。ide
下面摘录一段李刚的《疯狂iOS》,这段例子讲的很清楚,因此摘录在下面:svg
5.5.1 简单的 KVC
最基本的 KVC 由 NSKeyValueCoding 协议提供支持,最基本的操做属性的两个方法以下。
setValue:属性值 forKey:属性名:为指定属性设置值。
valueForKey:属性名:获取指定属性的值。
例如,以下程序定义了 FKUser 类的接口部分。
程序清单: codes/05/5.5/FKUser. H学习
#import <Foundation/ Foundation. H> @interface FKUser: NSobject //使用@property 定义 3 个 property @property (nonatomic, copy) NSString* name; @property (nonatomic, copy) NSString* pass; @property (nonatomic, copy) NSDate* birth; @end
上面程序定义了 FKUser 类使用@property 定义 3 个 property,接下来应该为该类定义实现部分,实现部分使用@synthesize 为这 3 个 property 合成 setter 和 getter 方法。类实现部分代码很是简单,故此处再也不给出。
下面使用 KVC 来设置 FKUser 对象的属性,以及访问 FKUser 对象的属性。程序代码以下:ui
程序清单: codes/05/5.5/FKUserTest.m #import "FKUser. H" int main (int argc,char★argv []) { @autoreleasepool { //建立 FKUser 对象 FKUser* user = [[FKUser alloc] init]; // 使用 KVC 方式为 name 属性设置属性值 [user setValue: @“孙悟空”forKey: @"name"]; //使用 KVC 方式为 pass 属性设置属性值 [user setValue: @"1455" forKey: @"pass"]; //使用 KVC 方式为 birth 属性设置属性值 [user setValue: [[NSDate alloc] init] forKey: @"birth"]; //使用KVC 获取 FKUser 对象的属性 NSLog (@"user 的 name 为:%@“,【user valueForKey: @"name"]); NSLog (@"user 的 pass 为:%@“,【user valueForKey: @"pass"]); NSLog (@"user 的 birth 为:%@”,【user valueForKey: @"birth"]);
上面程序中前 3 行粗体字代码使用 KVC 方式为属性设置属性值,后 3 行粗体字代码使用 KVC 模式获取指定属性的值。
编译、运行上面的程序,看到以下输出:atom
user 的 name 为:孙悟空 user 的 pass 为:1455 user 的 birth 为:2013-04-08 16:55:49 +0000
在 KVC 编程方式中,不管调用 setValue: forKey 方法,仍是调用 valueForKey:方法,都是经过 NSString 对象来指定被操做属性的,其中 forKey:标签用于传入属性名。
对于 setValue:属性值 forKey@"name“;代码,底层的执行机制以下。
(1) 程序优先考虑调用“setName:属性值;”代码经过 setter 方法完成设置。
(2) 若是该类没有 setName:方法,KVC 机制会搜索该类名为_ name 的成员变量,不管该成员变量是在类接口部分定义,仍是在类实现部分定义,也不管用哪一个访问控制符修饰,这条 KVC 代码底层实际上就是对 name 成员变量赋值。
(3) 若是该类既没有 setName:方法,也没有定义_ name 成员变量,KVC 机制会搜索该类名为 name 的成员变量,不管该成员变量是在类接口部分定义,仍是在类实现部分定义,也不管用哪一个访问控制符修饰,这条 KVC 代码底层实际就是对 name 成员变量赋值。
(4) 若是上面 3 条都没有找到,系统将会执行该对象的 setValue: forUndefinedKey:方法。
默认的 setValue: forUndefinedKey:方法实现就是引起一个异常,这个异常将会| 致使程序由于异常结束。
对于“valueforKey@“name”;,”代码,底层的执行机制以下。
(1) 程序优先考虑调用“name;”代码来获取该 getter 方法的返回值。
(2) 若是该类没有 name 方法,KVC 机制会搜索该类名为_ name 的成员变量,不管该成员变量是在类接口部分定义,仍是在类实现部分定义,也不管用哪一个访问控制符修饰,这条 KVC
代码底层实际就是返回_ name 成员变量的值。
(3) 若是该类既没有 name 方法,也没有定义_ name 成员变量,KVC 机制会搜索该类名为name 的成员变量,不管该成员变量是在类接口部分定义,仍是在类实现部分定义,也不管用哪一个访问控制符修饰,这条 KVC 代码底层实际就是返回 name 成员变量的值。
(4) 若是上面 3 条都没有找到,系统将会执行该对象的 valueforUndefinedKey:方法。
KVC的内容有点多,一章总结不完,这篇文章基本都是摘录了,由于李刚的文章写得至关清楚,那就经过摘录来加深印象。
https://developer.apple.com/documentation/foundation/object_runtime/nskeyvaluecoding?language=objc
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/index.html
https://www.objc.io/issues/7-foundation/key-value-coding-and-observing/