標籤:ios 工具類
功能
通過自訂Model基類,實現:
1、將json字典轉換成對象,無需考慮屬性名稱和字典鍵(key)的名稱的關係,即可以自訂映射關係。也支援字典中自訂對象的賦值。
2、一行代碼將對象轉換為json字典。
使用
讓自訂的Model類繼承自CYZBaseModel即可。然後根據需要選擇重寫或者調用的方法。
字典轉對象:
1、如果字典中的鍵的名稱與對象的屬性名稱一樣,則不需要重新任何方法,或者在attributeMapDictionary中返回nil即可。
2、如果字典中有任一鍵的名稱與對象屬性不一樣,則需要自己建立映射字典,即在attributeMapDictionary中返回自己建立的一個字典類對象,該字典中,以屬性名稱作為key,以“映射字典”(即傳入字典)的鍵作為value。聽起來可能比較繞,詳情一看代碼便知。
3、如果有自訂對象,則在setAttributeDictionary:中從字典中取出小字典並用它建立對象,然後賦值即可。
4、無論上述哪種情況,在建立你的自訂對象時都使用initWithDict:方法,傳入dictionary便可以自動轉成對象。
對象轉字典:
調用方法dictionaryRepresentation即可
實現思路
主要用到的知識點就是反射,或者說objc的runtime知識。對象轉字典,要擷取到對象中的所有屬性,然後把屬性名稱和屬性值存入字典即可。字典轉對象,就是先根據自己定義的映射字典(map dictionary)將自己的屬性名稱轉換為待轉換字典的key的名字,然後根據自己屬性的名字擷取setter方法,將待轉換字典中取出來的值作為setter的參數調用就行了。
代碼
對象轉字典:
- (NSDictionary *)dictionaryRepresentation { unsigned int count = 0; //get a list of all properties of this class objc_property_t *properties = class_copyPropertyList([self class], &count); NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:count]; NSDictionary *keyValueMap = [self attributeMapDictionary]; for (int i = 0; i < count; i++) { NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])]; id value = [self valueForKey:key]; NSLog(@"key = %@, value = %@, value class = %@, changed Key = %@", key, value, NSStringFromClass([value class]), [keyValueMap objectForKey:key]); key = [keyValueMap objectForKey:key]; //only add it to dictionary if it is not nil if (key && value) { [dict setObject:value forKey:key]; } } free(properties); return dict;}
字典轉對象:
- (id)initWithDict:(NSDictionary *)aDict{ self = [super init]; if (self) { //建立映射關係 [self setAttributesDictionary:aDict]; } return self;}- (NSDictionary *)attributeMapDictionary{ //子類需要重寫的方法 //NSAssert(NO, "You should override this method in Your Custom Class"); return nil;}- (void)setAttributesDictionary:(NSDictionary *)aDict{ //獲得映射字典 NSDictionary *mapDictionary = [self attributeMapDictionary]; //如果子類沒有重寫attributeMapDictionary方法,則使用預設映射字典 if (mapDictionary == nil) { NSMutableDictionary *tempDict = [NSMutableDictionary dictionaryWithCapacity:aDict.count]; for (NSString *key in aDict) { [tempDict setObject:key forKey:key]; } mapDictionary = tempDict; } //遍曆映射字典 NSEnumerator *keyEnumerator = [mapDictionary keyEnumerator]; id attributeName = nil; while ((attributeName = [keyEnumerator nextObject])) { //獲得屬性的setter SEL setter = [self _getSetterWithAttributeName:attributeName]; if ([self respondsToSelector:setter]) { //獲得映射字典的值,也就是傳入字典的鍵 NSString *aDictKey = [mapDictionary objectForKey:attributeName]; //獲得傳入字典的鍵對應的值,也就是要賦給屬性的值 id aDictValue = [aDict objectForKey:aDictKey]; //為屬性賦值 [self performSelectorOnMainThread:setter withObject:aDictValue waitUntilDone:[NSThread isMainThread]]; } }}- (SEL)_getSetterWithAttributeName:(NSString *)attributeName{ NSString *firstAlpha = [[attributeName substringToIndex:1] uppercaseString]; NSString *otherAlpha = [attributeName substringFromIndex:1]; NSString *setterMethodName = [NSString stringWithFormat:@"set%@%@:", firstAlpha, otherAlpha]; return NSSelectorFromString(setterMethodName);}
下載
項目地址:https://github.com/YiZhuoChen/CYZBaseModel
iOS開發——對象與字典互相轉換