欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS KVC-对象初始化赋值的神级技巧

程序员文章站 2023-01-11 21:02:29
ios kvc-对象初始化赋值的神级技巧。网络请求之后最重要的一步就是把字典数据转化成类对像了,这一步很简单,但通常也异常繁琐,因为为了使程序健壮,我们首先会判断字典中是否存在这个key对应的val...

ios kvc-对象初始化赋值的神级技巧。网络请求之后最重要的一步就是把字典数据转化成类对像了,这一步很简单,但通常也异常繁琐,因为为了使程序健壮,我们首先会判断字典中是否存在这个key对应的value,如果存在则赋值,不存在则跳过。

此篇文章将给出一个比较简单的初始化类对象的技巧,应用场景是最常见的通过字典数据初始化类对像。

原理是通过kvc提供的- (void)setvaluesforkeyswithdictionary:方法达到快速初始化的目的,代码简洁,不易出错。

demo如下:

//poiinfor.h
@interface poiinfor : nsobject

@property(nonatomic, assign)nsinteger   userid;
@property(nonatomic, assign)double      createtime;
@property(nonatomic, copy) nsstring     * summary;
@property(nonatomic, copy) nsstring     * content;
@property(nonatomic, strong)nsnumber    * inforid;
@property(nonatomic, strong)nsnumber    * likenum;
@property(nonatomic, strong)nsnumber    * readnum;
@property(nonatomic, strong)nsarray     * photos;//每个元素都是poiphoto类型
@property(nonatomic, strong)nsnumber    * iseditphoto;

/**
 通过字典创建并初始化一个类对像
题外话:
alt+command+/可给方法添加注释,按住alt点击方法名即会出现注释内容,类似系统api注释,建议以此方法添加注释
 */
+ (instancetype)infowithdictionary:(nsdictionary *)dict;
- (instancetype)initwithdictionary:(nsdictionary *)dict;

@end

//poiinfor.m
@implementation poiinfor

+ (instancetype)infowithdictionary:(nsdictionary *)dict
{
    return [[poiinfor alloc] initwithdictionary:dict];
}

- (instancetype)initwithdictionary:(nsdictionary *)dict{
    self = [super init];
    if (self) {
        //通过kvc方法可快速通过字典给对像赋值,将字典中的value赋值给与其key同名的property[基本数据类型(比如int等)无需做特殊处理]
        [self setvaluesforkeyswithdictionary:dict];
    }
    return self;
}

- (void)setvalue:(id)value forkey:(nsstring *)key{
    if ([key isequaltostring:@"id"]) {
        key = @"userid";
    }
    else if ([key isequaltostring:@"photos"]){
        //遍历value数组,按照和poiinfor相同的方式创建并初始化poiphoto对像
        __block nsmutablearray  * photos = [@[] mutablecopy];
        if ([value iskindofclass:[nsarray class]]) {
            [value enumerateobjectsusingblock:^(nsdictionary * _nonnull obj, nsuinteger idx, bool * _nonnull stop) {
                if ([obj iskindofclass:[nsdictionary class]]){
                    //poiphoto没有写便利构造器,可按步就班的初始化
                    poiphoto    * photo = [poiphoto new];
                    [photo setvaluesforkeyswithdictionary:obj];
                    [photos addobject:photo];
                }
            }];
        }
        value = photos;
    }

    [super setvalue:value forkey:key];
}
//此方法建议实现,否则很可能有崩溃风险
- (void)setvalue:(id)value forundefinedkey:(nsstring *)key{
    nslog(@" -- undefined key : %@ -- ",key);
    //当调用setvaluesforkeyswithdictionary:时,首先会调用setvalue:forkey:方法,当找不到key对应的property时,便会调用setvalue:forundefinedkey:方法进行进一步的处理
    //如果有此方法,则可以处理找不到的key,若未实现此方法,则程序会出现崩溃
    //因此为了保持程序健壮,使用setvaluesforkeyswithdictionary:方法初始化的类必须重写此方法,一般空实现即可
}

@end

从此以后便可丢弃一大串的if-else了,是不是很爽?
夜深人静,天明还要上班,写得比较捉急,不明白的地方欢迎留言讨论,该方法如有不妥或不足之处,欢迎指正。