iOS KVC(一)基本了解
iOS KVC (二) 不可不知的賦值深層次原理
iOS KVC (三)不可不知的取值深層次原理
iOS KVC (四)keyPath的深度解析
iOS KVC (五)KVC幾種典型的異常處理
iOS KVC (六) KVC容器類及深層次原理
iOS KVC(七) KVC正確性的驗證
iOS KVC (八) KVC幾種常見應(yīng)用
iOS KVC (九) KVC模型轉(zhuǎn)化(1) 模型打印 description, debugDescription
iOS KVC (十)模型轉(zhuǎn)換(2)模型轉(zhuǎn)換
本章主要講單層次的模型轉(zhuǎn)換 后期學(xué)習(xí)任務(wù)歸結(jié)到 YYModel ,JsonModel,MJExtension的源碼分析是會不發(fā) 此章也是模型轉(zhuǎn)換的基礎(chǔ)。
1傳統(tǒng)設(shè)置方法
直接上代碼
1.Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)int age;
+ (instancetype)personWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
@end
2.Person.m
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
- (NSString *)description{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//得到當(dāng)前class的所有屬性
uint count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0; i<count; i++) {
objc_property_t property = properties[i];
NSString *name = @(property_getName(property));
id value = [self valueForKey:name]?:[NSNull null];//默認值不可為為nil的字符串
[dic setObject:value forKey:name];
}
free(properties);
return [NSString stringWithFormat:@"%@:%@",[self class],dic];
}
+ (instancetype)personWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];
if (self) {
// 方法 1,直接設(shè)置,基本數(shù)據(jù)類型需要轉(zhuǎn)換
_name = dict[@"name"];
_age = [dict[@"age"] intValue];
}
return self;
}
3.實例調(diào)用
#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.
NSDictionary *dic = @{
@"name":@"小明",
@"age":@10,
@"address":@"河南"
};
Person *p = [Person personWithDict:dic];
NSLog(@"%@",p);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
4.打印數(shù)據(jù)
018-05-18 20:50:38.774764+0700 KVCDemo[4798:382355] Person:{
age = 10;
name = "\U5c0f\U660e";
}
5.總結(jié):
無論字典中有沒有包含模型的字段,都不會導(dǎo)致崩潰,包含賦值,不包含不賦值,多不退,少不補。
2KVC基礎(chǔ)設(shè)置方法
1.Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,copy)NSString * _Nullable name;
@property (nonatomic,assign)int age;
@property (nonnull,copy)NSString *adress;
+ (instancetype _Nullable )personWithDict:(NSDictionary *_Nullable)dict;
- (instancetype _Nullable )initWithDict:(NSDictionary *_Nullable)dict;
@end
2.Person.m
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
- (NSString *)description{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//得到當(dāng)前class的所有屬性
uint count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0; i<count; i++) {
objc_property_t property = properties[i];
NSString *key = @(property_getName(property));
id value = [self valueForKey:key]?:[NSNull null];//此處不能為nil 因為字典中盡量不要出現(xiàn)nil 應(yīng)該為[NSNull null]
[dic setObject:value forKey:key];
}
free(properties);
return [NSString stringWithFormat:@"%@:%@",[self class],dic];
}
+ (instancetype)personWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];
if (self) {
[self setValue:dict[@"name"] forKey:@"name"];
[self setValue:dict[@"age"] forKey:@"age"];
[self setValue:dict[@"adress"] forKey:@"adress"];
}
return self;
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@"不存在Key:%@",key);
}
- (void)setNilValueForKey:(NSString *)key{
NSLog(@"屬性值不能為nil");
}
@end
3.調(diào)用
#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.
NSDictionary *dic = @{
@"name":[NSNull null],
@"adress":@"河南",
@"age":@10
};
Person *p = [Person personWithDict:dic];
NSLog(@"%@",p);
}
4.打印數(shù)據(jù):
2018-05-18 22:38:44.749136+0700 KVCDemo[6297:464723] Person:{
adress = "\U6cb3\U5357";
age = 10;
name = "<null>";
}
5.總結(jié):
1 - (void)setValue:(id)value forUndefinedKey:(NSString *)key
模型中不存在這個key會調(diào)用此方法。
2- (void)setNilValueForKey:(NSString *)key
當(dāng)模型中的整形不存在時調(diào)用此方法。 并且如果整形不存在系統(tǒng)會將0賦予這個整型的字段。
3.這兩個方法是必須執(zhí)行的,因為如果不執(zhí)行,如果存在不存在的key 或者模型的整形字段不存在,都會導(dǎo)致程序的崩潰。
3遍歷字典
1.Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,copy)NSString * _Nullable name;
@property (nonatomic,assign)int age;
@property (nonnull,copy)NSString *adress;
+ (instancetype _Nullable )personWithDict:(NSDictionary *_Nullable)dict;
- (instancetype _Nullable )initWithDict:(NSDictionary *_Nullable)dict;
@end
2.Person.m
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
- (NSString *)description{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//得到當(dāng)前class的所有屬性
uint count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0; i<count; i++) {
objc_property_t property = properties[i];
NSString *key = @(property_getName(property));
id value = [self valueForKey:key]?:[NSNull null];//此處不能為nil 因為字典中盡量不要出現(xiàn)nil 應(yīng)該為[NSNull null]
[dic setObject:value forKey:key];
}
free(properties);
return [NSString stringWithFormat:@"%@:%@",[self class],dic];
}
+ (instancetype)personWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];
if (self) {
for (NSString *key in dict) {
id value = dict[key];
[self setValue:value forKey:key];
}
}
return self;
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@"不存在Key:%@",key);
}
- (void)setNilValueForKey:(NSString *)key{
NSLog(@"屬性值不能為nil");
}
- (BOOL)validatePersonName:(id *)value error:(out NSError * _Nullable __autoreleasing *)outError
{
NSString *name = *value;
if ([name isEqualToString:@"小明"]) {
return YES;
}
return NO;
}
3.調(diào)用
#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.
NSDictionary *dic = @{
@"name":[NSNull null],
@"adress":@"河南",
@"age":@10
};
Person *p = [Person personWithDict:dic];
NSLog(@"%@",p);
}
4.打印數(shù)據(jù):
2018-05-19 16:17:55.638697+0700 KVCDemo[7364:534839] Person:{
adress = "\U6cb3\U5357";
age = 10;
name = "<null>";
}
5.總結(jié):
寫到此刻我已經(jīng)無話可說了,只是一種方式。
4. setValuesForKeysWithDictionary
1.Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,copy)NSString * _Nullable name;
@property (nonatomic,assign)int age;
@property (nonnull,copy)NSString *adress;
+ (instancetype _Nullable )personWithDict:(NSDictionary *_Nullable)dict;
- (instancetype _Nullable )initWithDict:(NSDictionary *_Nullable)dict;
@end
2.Person.m
#import "Person.h"
#import <objc/runtime.h>
@implementation Person
- (NSString *)description{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//得到當(dāng)前class的所有屬性
uint count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0; i<count; i++) {
objc_property_t property = properties[i];
NSString *key = @(property_getName(property));
id value = [self valueForKey:key]?:[NSNull null];//此處不能為nil 因為字典中盡量不要出現(xiàn)nil 應(yīng)該為[NSNull null]
[dic setObject:value forKey:key];
}
free(properties);
return [NSString stringWithFormat:@"%@:%@",[self class],dic];
}
+ (instancetype)personWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@"不存在Key:%@",key);
}
- (void)setNilValueForKey:(NSString *)key{
NSLog(@"屬性值不能為nil");
}
- (BOOL)validatePersonName:(id *)value error:(out NSError * _Nullable __autoreleasing *)outError
{
NSString *name = *value;
if ([name isEqualToString:@"小明"]) {
return YES;
}
return NO;
}
3.調(diào)用
#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.
NSDictionary *dic = @{
@"name":[NSNull null],
@"adress":@"河南",
@"age":@10
};
Person *p = [Person personWithDict:dic];
NSLog(@"%@",p);
}
4.打印數(shù)據(jù):
2018-05-19 16:29:15.202777+0700 KVCDemo[7492:542825] Person:{
adress = "\U6cb3\U5357";
age = 10;
name = "<null>";
}
5.總結(jié):
此方法等同于遍歷字典,設(shè)置數(shù)據(jù),等同于方法3
分享幾篇關(guān)于模型多層轉(zhuǎn)化的文章,希望對大家有所幫助。
iOS - 教你一步一步實現(xiàn)自己的字典轉(zhuǎn)模型庫
iOS開發(fā)·runtime+KVC實現(xiàn)多層字典模型轉(zhuǎn)換(多層數(shù)據(jù):模型嵌套模型,模型嵌套數(shù)組,數(shù)組嵌套模型)
到此為止關(guān)于KVC的基礎(chǔ)知識就已經(jīng)完結(jié)了,希望對你有所幫助。接下分享KVO。