iOS之KVC使用
还是老样子,先翻译KVC
** KVC:Key Value Coding (键值编码)**
作用:
- KVC可以用来访问和设置实例变量的值( key为属性名)
- 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
** 情况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)/~