通过自定义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);
}
原文:http://blog.csdn.net/u013604612/article/details/45398041