细节1:
我们在项目中使用kvc,在设置model属性的时候,注意尽量不要使用基本数据类型。
实例:
数据模拟:注意age是null类型的
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
/** 名称 **/
@property(nonatomic,strong)NSString * username;
/** 年龄 **/
//技巧:使用NSNumber 记录数值,可以避免后台返回 null,无法返回kvc
@property(nonatomic,assgin)int age;
@end
我们可以使用 @property(nonatomic,assgin)int age;
定义属性,但是当数据为null的时候,程序就会崩溃。
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL * url = [NSURL URLWithString:@"http://127.0.0.1/demo.json"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//反序列化
NSArray * result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
for (NSDictionary * dict in result) {
Person * p =[[Person alloc]init];
//kvc赋值
[p setValuesForKeysWithDictionary:dict];
NSLog(@"%@ %d",p.username,p.age);
}
}];
}
错误信息告诉我们,有一个id属性没有定义。我们在model中重写
-(void)setValue:(id)value forUndefinedKey:(NSString *)key;
运行程序,结果还是崩溃
那么,好吧,我们只能这么处理
Person.m
#import "Person.h"
@implementation Person
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
-(void)setNilValueForKey:(NSString *)key{
}
@end
加入我们使用NSNumber定义模型属性
#import <Foundation/Foundation.h>
@interface Person : NSObject
/** 名称 **/
@property(nonatomic,strong)NSString * username;
/** 年龄 **/
//技巧:使用NSNumber 记录数值,可以避免后台返回 null,无法返回kvc
@property(nonatomic,strong)NSNumber * age;
@end
#import "Person.h"
@implementation Person
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
//
//-(void)setNilValueForKey:(NSString *)key{
//
//}
@end
那么我们就不需要担心后台返回给我们数据null的情况了
细节2:
使用kvc,在定义模型属性的时候,假如我们定义的属性与数据中的key不一致,那么kvc是找不到的
注意,KVC做了优化,对于模型属性的首字母大写,kvc可以自动识别到
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL * url = [NSURL URLWithString:@"http://127.0.0.1/demo.json"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//反序列化
NSArray * result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
for (NSDictionary * dict in result) {
Person * p =[[Person alloc]init];
//kvc赋值
[p setValuesForKeysWithDictionary:dict];
NSLog(@"%@ %@ %@",p.ID,p.Username,p.age);
}
}];
}
#import <Foundation/Foundation.h>
@interface Person : NSObject
/** id **/
@property(nonatomic,strong)NSNumber * ID;
/** 名称 **/
@property(nonatomic,strong)NSString * Username;
/** 年龄 **/
//技巧:使用NSNumber 记录数值,可以避免后台返回 null,无法返回kvc
@property(nonatomic,strong)NSNumber * age;
@end
我们可以重写-(void)setValue:(id)value forUndefinedKey:(NSString *)key
解决这个问题