iOS之KVC使用

作者: helloDolin | 来源:发表于2016-02-18 19:13 被阅读441次

    还是老样子,先翻译KVC
    ** KVC:Key Value Coding (键值编码)**


    作用:

    1. KVC可以用来访问和设置实例变量的值( key为属性名)
    2. KVC很暴力,可以访问私有属性或者私有变量,但是这个变量必须是以 _打头才可以(这篇文章不演示,因为不常用)

    还是老样子,直接上代码:
    首先我们先创建一个model,这里以Student为例,在.m文件中重写description方法(方便调试)

    #import <Foundation/Foundation.h>
    @interface Student : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *sex;
    
    @end
    
    #import "Student.h"
    
    @implementation Student
    
    - (NSString*)description {
        return [NSString stringWithFormat:@"\nname:%@\nsex:%@",self.name,self.sex];
    }
    
    @end
    

    新建command line项目(也是方便调试),这篇文章主要示例Dictionary转model

    #import <Foundation/Foundation.h>
    #import "Student.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            NSDictionary* dic = @{
                                  @"name":@"爪",
                                  @"sex":@"true",
                                 };
            
            Student* model = [Student new];
            [model setValuesForKeysWithDictionary:dic];
            NSLog(@"%@",model);
        }
        return 0;
    }
    

    运行看到以下结果

    运行结果

    ** 下面试试其他情况 **
    ** 情况1: **先在在Student类中新增一个age属性

    #import <Foundation/Foundation.h>
    @interface Student : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *sex;
    @property (nonatomic, copy) NSString *age;
    
    @end
    
    #import "Student.h"
    @implementation Student
    
    - (NSString*)description {
        return [NSString stringWithFormat:@"\nname:%@\nsex:%@\nage:%@",self.name,self.sex,self.age];
    }
    
    @end
    

    运行:

    运行结果

    运行是没有问题的,_age变量值为null

    ** 情况2: **字典扩充一个 @"address":@"USA"


    字典扩充

    运行:
    崩溃了


    运行结果 控制台

    控制台报的错也是很容易懂的,这里就不翻译了,主要说一下解决办法

    这个时候我们可以这样解决
    在Student类中增加 - (void)setValue:(id)value forUndefinedKey:(NSString *)key;

    @interface Student : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *sex;
    @property (nonatomic, copy) NSString *age;
    
    - (void)setValue:(id)value forUndefinedKey:(NSString *)key;
    
    @end
    

    在.m文件中实现这个方法

    - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
        NSLog(@"没有这个  %@   key",key);
    }
    

    自己可以运行看结果哈,不会再崩溃了

    ** KVC 官方API **
    Foundation框架下,NSKeyValueCoding

    KVC 官方API

    ** 情况3: ** 服务器返回的json中含有id这样的key
    当服务器放回给这样的key的话,个人建议还是不要用,(我们项目中这样用了,暂时没发现问题,但是还是建议不要这样用)因为id是OC的关键字,可以这样改:(这边用大写的ID)

    @interface Student : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *sex;
    @property (nonatomic, copy) NSString *age;
    @property (nonatomic, copy) NSString *ID;
    
    - (void)setValue:(id)value forUndefinedKey:(NSString *)key;
    
    @end
    

    .m文件中

    - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
        if ([key isEqualToString:@"id"]) {
            self.ID = value;
        }
    }
    

    好的设计:

    如果我们每个model都去- (void)setValue:(id)value forUndefinedKey:(NSString *)key; 岂不是很麻烦
    这个时候我们可以创建一个model父类,在这个父类中去处理这样的逻辑,然后自己创建的model继承父类model就ok了


    希望会给大家带来帮助(o)/~

    相关文章

      网友评论

      • helloDolin:不用model的话,就直接用字典,现在去model的APP也是比较多的
        这个时候就需要和后台高度配合了,和后台制定好规则后,对应的key-value一般都不要再变化了,按照这样的规则后也就不用判断了
      • 来宝:大神,如果我不用model怎么弄?比如后台就返回一个键值对{name:joy}怎么搞?也不能每次都判断字典里是否包含name呀

      本文标题:iOS之KVC使用

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