Swift 学习笔记

1.暴力而强大的KVC

访问属性

NSObject遵循了NSKeyValueCoding协议,凡是继承自NSObject的类都是可以使用KVC机制的,并且NSObject已经提供了使用KVC的一些基本方法,如:

- (nullable id)valueForKeyPath:(NSString*)keyPath;

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

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

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

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

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

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

1、使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。

2、无论是否提供getter/setter方法,无论可见性是怎样,是否有readonly修饰,KVC可以访问成员变量,或者修改成员变量,这使得kvc在某些情况下有非常大的用处。

键值编码

在key字符串中,可以使用 '点符号 '来连接路径,见下面的代码示例

[itemSetValue:@"test" forKeyPath:@"myClass.name"];

此外,还可以应用一些字符做简单运算。@+sum,min,max,avg,count,见下面的代码示例

//属性相加

NSString*sum=[person valueForKeyPath:@"[email protected]"];

//数量

NSString*count=[person valueForKeyPath:@"[email protected]"];

//最大值

NSString*max=[person valueForKeyPath:@"[email protected]"];

//最小值

NSString*min=[person valueForKeyPath:@"[email protected]"];

//平均值

NSString*avg=[person valueForKeyPath:@"[email protected]"];




OC中和Swift中的区别

1.在OC中,想要对一个属性赋值,必须自己输入属性对应的字符串

[person setValue:@18  forKey:@"age"]

注意,age在定义时定义为int类型,属于基本数据类型,但是在KVC中会将age包装成NSNumber或者NSValue等类型进行操作。

在swift中,进一步的优化是不用再自己输入这个不一定正确的字符串了,我们可以使用#keyPath来输入key,这样编译器会对key进行判断

self.setValue(18, forKeyPath: #keyPath(Person.age))

2.swift中由于引入了可选类型,如果把基本类型定义为可选类型,此时使用KVC会导致无法识别的键值错误,因为KVC是从OC的一种机制,而OC中基本数据类型不存在值缺省,所以无法处理可选的基本数据类型

var name:String?

var phone:Int? =0

self.setValuesForKeys(dic)  // 这样写会导致undefinedKey异常

解决方案:

方案一:如果一定要使用KVC,基本数据类型不要定义为可选类型,并且要对基本数据类型进行初始化

var name:String?

var phone:Int = 0

super.init()  // 注意使用KVC之前必须点用父类的初始化方法,确保属性完成初始化,否则会报错

self.setValuesForKeys(dic)

方案二:如果基本数据类型必须定义为可选的,则不要使用KVC

name = dic["name"] as! String?

phone = dic["phone"] as! Int?

你可能感兴趣的:(Swift 学习笔记)