標籤:
一、字典轉模型的索引值對與模型屬性不匹配問題
1. 字典的鍵個數 < 模型的屬性個數 (key 能與模型的屬性匹配)
1> .KVO 方式:
- setValuesForKeysWithDictionary:
2> for迴圈的方式,一一賦值
2.字典的鍵個數 = 模型的屬性個數 (key 能與模型的屬性匹配)
同1。
3.字典的個數 > 模型的屬性個數 (模型的屬性為字典key 的其中一部分)
一共有三種解決方式
二、解決辦法:
建立一個GXApp的模型,申明兩個屬性: name(名稱) details(詳細資料),在類方法中是直接使用
在控制器中使用:
直接運行:
Terminating app due to uncaught exception ‘NSUnknownKeyException‘,
reason: ‘[<GXApp 0x7ff1a8d41790> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key version .‘
解決辦法一:
在類方法中,一個個屬性賦值
1 // 2 // GXApp.m 3 // B01-字典轉模型的屬性不匹配問題 4 // 5 // Created by gxiangzi on 15/8/25. 6 // Copyright (c) 2015年 hqu. All rights reserved. 7 // 8 9 #import "GXApp.h"10 11 @implementation GXApp12 13 + (instancetype)appWithDict:(NSDictionary*)dict14 {15 GXApp* app = [[GXApp alloc] init];16 17 // 利用數組儲存 模型的屬性18 NSArray* parameters = @[ @"name", @"details" ];19 // 遍曆字典,判斷模型是否有該屬性20 [parameters enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop)21 {22 if (dict[obj])23 {24 [app setValue:dict[obj] forKey:obj];25 }26 }];27 28 return app;29 }30 31 @end
缺點: 該種方式對極少數屬性相對簡單,但是擴充性不高。
解決辦法二
運行是機制,在運行時,判斷模型的屬性,然後賦值
1 // 2 // GXApp.m 3 // B01-字典轉模型的屬性不匹配問題 4 // 5 // Created by gxiangzi on 15/8/25. 6 // Copyright (c) 2015年 hqu. All rights reserved. 7 // 8 9 #import "GXApp.h"10 #import <objc/runtime.h>11 12 @implementation GXApp13 14 + (instancetype)appWithDict:(NSDictionary *)dict15 {16 GXApp *app = [[GXApp alloc] init];17 18 NSArray *array = [app getProperties];19 20 21 // 根據屬性的值,去資料字典中取對應的值22 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {23 // key 屬性值.24 NSString *key = obj;25 26 if (dict[key]) {27 28 [app setValue:dict[key] forKey:key];29 }30 31 }];32 33 return app;34 }35 36 // 動態擷取某一個類的屬性.37 - (NSArray *)getProperties38 {39 unsigned int count;40 41 // 擷取一個類中的屬性42 objc_property_t *properties = class_copyPropertyList(self.class, &count);43 44 NSMutableArray *array = [NSMutableArray array];45 46 // 遍曆類中的屬性,將每一個屬性值都轉換成 OC 的字串47 for (int i = 0; i < count; i++) {48 49 // pro 依然是 C 語言的資料類型50 objc_property_t pro = properties[i];51 52 // 指向C 語言字串一個指標.53 const char *name = property_getName(pro);54 55 NSString *property = [[NSString alloc] initWithUTF8String:name];56 57 [array addObject:property];58 }59 60 return array;61 }62 63 @end
缺點:運行時代碼,C語言代碼,代碼不易記住
解決辦法三、
重寫 - setValuesForKeysWithDictionary:
//// GXApp.m// B01-字典轉模型的屬性不匹配問題//// Created by gxiangzi on 15/8/25.// Copyright (c) 2015年 hqu. All rights reserved.//#import "GXApp.h"@implementation GXApp+(instancetype)appWithDict:(NSDictionary *)dict{ GXApp *app = [[GXApp alloc] init]; [app setValuesForKeysWithDictionary:dict]; return app;}- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ // do nothing}@end
解釋:
官方解釋:
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
Given that an invocation of -setValue:forKey: would be unable to set the keyed value because the type of the parameter of the corresponding accessor method is an NSNumber scalar type or NSValue structure type but the value is nil, set the keyed value using some other mechanism. The default implementation of this method raises an NSInvalidArgumentException. You can override it to map nil values to something meaningful in the context of your application.
當利用kvo賦值的適合,如果索引值不匹配,就會報一個 NSInvalidArgumentException 異常,可以重寫這個方法可以解決
【IOS問題】字典轉模型,屬性個數不匹配問題