iOS KVC (十)模型轉(zhuǎn)換

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。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,286評論 8 265
  • 為加大社會保險宣傳力度,推進城鎮(zhèn)企業(yè)職工養(yǎng)老保險制度健康穩(wěn)步運行,26日,綏濱縣社保局開展了以“社會保險,...
    丁小孩閱讀 867評論 0 0
  • 曾經(jīng)的我有段時間非常迷戀奇葩說。被里面的辯論深深吸引,我常常感嘆,他們真的是為辯論而生,她們的妙語連珠,精彩紛呈,...
    深夜靈感閱讀 231評論 0 0
  • 朋友圈充斥著每個朋友對2017的美好回憶。 而對我來說,這是極度不平凡的一年。 2017,1月7日回到汕頭,決定要...
    Oh_930f閱讀 191評論 0 0
  • 我愛無名的罪 大地的根深埋土壤 鉆透人世間的悲歡離合 我也愛世俗的眼 天空的魚是徹底的藍 自由地遨翔是終生的命 我...
    伍月的晴空閱讀 293評論 8 8

友情鏈接更多精彩內(nèi)容