zoukankan      html  css  js  c++  java
  • [iOS]开发之-字典转模型和KVC

    需求一:将字典转换成自己需的对象,对象的属性是字典的key值,直接使用key值获取数据存在两个缺点,一是key值难以记忆,二是直接使用key值Xcode不会有智能提示,很容易导致未知的错误。使用模型时,可以直接通过点语法将需要的数据点出,保证数据准确无误。使用模型的优点还在于存储、传值都比较方便,不容易出错。最主要的是这也符合我们MVC和MVVM的设计模式。

     

    注意:要使用模型就离不开KVC,假如我们从外界传入一个字典,字典中有两个 key对应的值是我们需要的,这两个值分别是 “name”、“age”。要使用KVC的时候要注意模型的属性一定要和字典中的key值相对应。比如字典中的“name”,那模型中就必须有一个name的属性。这样就可以使用KVC了,KVC的两种方法:(下文都默认我们有两个模型属性,分别是name和age,传入的字典默认为dict)

     

    1. setValue(模型属性, forKey:字典的key值)

    eg:setValue(self.name, forKey:dict[“name”])

     

    *这种赋值方法很麻烦,每需要一个key值就要打一遍该方法。这样的赋值方式就和self.name = dict[“name”] 的区别不是太大

    2. setValuesForKeysWithDictionary(传入的字典)         

    eg: setValuesForKeysWithDictionary(dict)

    *直接完成赋值,其实setValuesForKeysWithDictionary(传入的字典),它默认也是调用setValue(模型属性, forKey:字典的key值 ),遍历字典一一给模型属性赋值。所以使用KVC时就要求模型的属性必须喝字典的key值一一对应。

    需求二:如果我们只想使用字典中的部分值呢?一个大字典,里面有好几十个key,难道我们还要在模型中根据key值定义几十个属性么?当然我们程序猿都是很懒的,肯定不会定义这么多key值的,此时我们只需重写KVC的以下方法就行了:        

    3.setValue(value: AnyObject?, forUndefinedKey key: String)

    *这个方法会帮我们过滤我们没有的key值,值执行 setValuesForKeysWithDictionary(dict)时,当监测出我们没有字典中key值所对应的属性时就会调用这个方法。                           

     *重写时里面不需要写任何代码,如果想打印哪些key值我们没有时就可以在里面打印。

    需求三:我们知道很多字典中都有“id”这个key值。而“id”在我们iOS中是个数据类型,显然不能将“id”当作模型属性名称去定义。此时我们只需要随意定义一个属性名去保存“id”,当然为了更已读、严谨一些,我们一般还是定义为“ID”最为恰当。而我们知道要使用KVC就要key值和模型名一一对应,但是我们就是想要获取“id”。此时需要将“需求一”和“需求二”结合起来看了。我们在获取“id”时,直接使用传入的字典赋值:(此时我们新添一个属性“ID”)

    eg :self.ID = dict[“id”]

    *当这样赋值之后就取出”id “所对应的value了。

    但是我们还要获取其他的value呢,此时在使用 setValuesForKeysWithDictionary(dict)完成其他属性的赋值。当然也需要重写setValue(value: AnyObject?, forUndefinedKey key: String)方法,因为字典中并有“ID”这个key值(字典中是“id”,“ID”是模型新定义的属性)。完整代码如下 :

    swift:

    override init() {

         super.init()

         self.ID = dict[@"id”];

         setValuesForKeysWithDictionary(dict)

    }    

    override func setValue(value: AnyObject?, forUndefinedKey key: String) { }

    OC:

    + (instancetype) testWithDict:(NSDictionary *)dict{

        

        TEST *test = [[TEST alloc]init];

        

        test.ID = dict[@"id"];

        

        [test setValuesForKeysWithDictionary:dict];

        

        return test;

    }

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

    }

    *注意当在对象方法使用KVC时一定要先super.init,因为要首先保证有一个对象存在,这样才能访问这个对象的属性。

    *注意在使用对象方法时,命名方法名时“With”中的“W”必须大写,否则无法完成super.init

    eg:- (instancetype) initWithDict:(NSDictionary *)dict

    补充:KVC强大不仅仅只在于给模型赋值,KVC还可给只读 属性赋值,改变私有属性。比如UITabBarController中tabBar是只读属性,用一般的赋值时无法给只读属性赋值的,但是通过

    setValue(value,forKey:”属性名”)

    eg:setValue(value,forKey:“tabBar”)

    总结:KVC是Set Value Coding的简称,它是一种直接通过字符串的名字(key)来访问类属性的机制。而不是通过Setter(设置器)和Getter(读取器)。

  • 相关阅读:
    字符编码相关
    函数之形参与实参
    文件操作模式
    函数对象,名称空间,作用域,和闭包
    吴裕雄天生自然SPRINGBOOT开发实战处理'spring.datasource.url' is not specified and no embedded datasource could be autoconfigured
    吴裕雄天生自然SPRINGBOOT开发实战处理XXXX that could not be found.
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot HTML表单登录
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot REST示例
    吴裕雄天生自然SpringBoot开发实战学习笔记处理 Could not write metadata for '/Servers'.metadata\.plugins\org.eclipse.core.resources\.projects\Servers\.markers.snap (系统找不到指定的路径。)
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot Tomcat部署
  • 原文地址:https://www.cnblogs.com/wanglekai/p/5410931.html
Copyright © 2011-2022 走看看