美文网首页
Swift 学习笔记

Swift 学习笔记

作者: stephen123 | 来源:发表于2017-02-23 20:03 被阅读0次

    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:@"rePerson.@sum.age"];

    //数量

    NSString*count=[person valueForKeyPath:@"rePerson.@count.age"];

    //最大值

    NSString*max=[person valueForKeyPath:@"rePerson.@max.age"];

    //最小值

    NSString*min=[person valueForKeyPath:@"rePerson.@min.age"];

    //平均值

    NSString*avg=[person valueForKeyPath:@"rePerson.@avg.age"];


    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 学习笔记

          本文链接:https://www.haomeiwen.com/subject/aimbwttx.html