Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
ijoyc committed Apr 30, 2015
0 parents commit ea356d9
Showing 3 changed files with 163 additions and 0 deletions.
41 changes: 41 additions & 0 deletions CYZBaseModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// CYZBaseModel.h
// HappyRead
//
// Created by YiZhuo Chen on 14-8-8.
// Copyright (c) 2014年 陈一卓. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CYZBaseModel : NSObject

/**
*初始化方法,将传入字典的key对应的value赋值给Model对象中相应地属性。
*@param aDict a Dictionary 该字典的key与attributeMapDictionary方法返回的字典的value同名,该字典的value为欲为属性赋的值
*@return 返回实例变量
*/
- (id)initWithDict:(NSDictionary *)aDict;

/**
*子类需要重写的方法,用以创建映射字典。
*在该方法中将属性名称作为key值,与初始化时传入字典的key同名的字符串作为value。
*若不重写,则返回nil,此时默认映射字典的key=value=初始化时传入字典的key同名的字符串。
*@return 返回一个映射字典,或者nil(如果子类不重写)
*/
- (NSDictionary *)attributeMapDictionary;

/**
*为实例变量赋以新的属性映射字典。
*另外,如果传入字典的值有非基本类(例如自己定义的类),需要重写该方法,
*调用[super setAttributesDictionary:aDict],然后将非基本类作为值为属性赋值
*@param aDict a Dictionary 新的属性映射字典
*/
- (void)setAttributesDictionary:(NSDictionary *)aDict;

/**
* 将自定义的对象转换成字典对象,属性名为键,属性值为值。
*/
- (NSDictionary *)dictionaryRepresentation;

@end
104 changes: 104 additions & 0 deletions CYZBaseModel.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// CYZBaseModel.m
// HappyRead
//
// Created by YiZhuo Chen on 14-8-8.
// Copyright (c) 2014年 陈一卓. All rights reserved.
//

#import "CYZBaseModel.h"
#import <objc/runtime.h>

@interface CYZBaseModel ()

- (SEL)_getSetterWithAttributeName:(NSString *)attributeName;

@end

@implementation CYZBaseModel

- (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]];
}
}
}

- (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;
}

#pragma mark - Private Methods

- (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);
}

@end
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# CYZBaseModel

## Usage

Just custom your model class by inheriting CYZBaseModel and override some methods if needed.

### Dictionary to object

If the name of class attribute is the same one as the key of dictionary, then just call -initWithDict:.

If the any one of class attribute name is different from the given dictionary's key, then override the method -(NSDictionary *)attributeMapDictionary to return a dictionary for mapping.
This dictionary use the "attribute name" as key and use "passing dictionary's key" as value.

If there is any attribute that is not basic data type, ie. custom class, Then override -setAttributesDictionary:(Nsdictionary *)adict to set the value manually.

### Object to dictionary

Call method -(NSDictionary *)dictionaryRepresentation and it will return a dictionary automatically.

0 comments on commit ea356d9

Please sign in to comment.