將字典轉化為模型,面向模型開發,是在開發中最為常用的功能。利用KVC可以將字典轉換為模型,但是前提有三個約束,一個是必須保證模型的屬性個數大于等于字典個數,二是屬性名稱與字典的key必須相同,三是對于模型中的基本數據類型無法轉換。
其中第一條與第三條,是其最大的弊端。例如,如果從服務器獲取的數據字典,并不想使用所有的鍵值對。但是在開發中還是必須得全部將對應屬性列出,全部進行轉換(除非你一個一個寫,不使用KVC)。
下面的代碼就可以解決上述問題:實現以模型為主,將字典數據進行部分轉化,并識別基本數據類型。約束僅僅是要求模型屬性名稱與字典KEY保持一致(因為底層還是使用KVC);
1 // 2 // NSObject+Value.m 3 // 4 // Created by shunzi 5-10-2014. 5 // Copyright (c) 2014年 shunzi. All rights reserved. 6 // 7 8 #import "NSObject+Value.h" 9 #import <objc/message.h>10 #import <objc/runtime.h>11 12 @implementation NSObject (Value)13 - (void)setValues:(NSDictionary *)values14 {15 Class c = [self class];16 17 while (c) {18 // 1.獲得所有的成員變量19 unsigned int outCount = 0;20 Ivar *ivars = class_copyIvarList(c, &outCount);21 22 for (int i = 0; i<outCount; i++) {23 Ivar ivar = ivars[i];24 25 // 2.屬性名26 NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];27 28 // 刪除最前面的_29 [name replaceCharactersInRange:NSMakeRange(0, 1) withString:@""];30 31 // 3.取出屬性值32 NSString *key = name;33 if ([key isEqualToString:@"desc"]) {34 key = @"description";35 }36 if ([key isEqualToString:@"ID"]) {37 key = @"id";38 }39 id value = values[key];40 if (!value) continue;41 42 // 4.SEL43 // 首字母44 NSString *cap = [name substringToIndex:1];45 // 變大寫46 cap = cap.uppercaseString;47 // 將大寫字母調換掉原首字母48 [name replaceCharactersInRange:NSMakeRange(0, 1) withString:cap];49 // 拼接set50 [name insertString:@"set" atIndex:0];51 // 拼接冒號:52 [name appendString:@":"];53 SEL selector = NSSelectorFromString(name);54 55 // 5.屬性類型56 NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];57 58 if ([type hasprefix:@"@"]) { // 對象類型59 objc_msgSend(self, selector, value);60 } else { // 非對象類型61 if ([type isEqualToString:@"d"]) {62 objc_msgSend(self, selector, [value doubleValue]);63 } else if ([type isEqualToString:@"f"]) {64 objc_msgSend(self, selector, [value floatValue]);65 } else if ([type isEqualToString:@"i"]) { 66 objc_msgSend(self, selector, [value intValue]);67 } else { 68 objc_msgSend(self, selector, [value longLongValue]);69 }70 }71 }72 73 c = class_getSuperclass(c);74 }75 }76 @end
頭文件僅僅包含對此方法的聲明,所以不在此粘貼
新聞熱點
疑難解答