首页 > 代码库 > 用字典给Model赋值

用字典给Model赋值

用字典给Model赋值

此篇教程讲述通过runtime扩展NSObject,可以直接用字典给Model赋值,这是相当有用的技术呢。

源码:

NSObject+Properties.h 与 NSObject+Properties.m

////  NSObject+Properties.h////  Created by YouXianMing on 14-9-4.//  Copyright (c) 2014年 YouXianMing. All rights reserved.//#import <Foundation/Foundation.h>@interface NSObject (Properties)- (void)setDataDictionary:(NSDictionary*)dataDictionary;- (NSDictionary *)dataDictionary;@end
////  NSObject+Properties.m////  Created by YouXianMing on 14-9-4.//  Copyright (c) 2014年 YouXianMing. All rights reserved.//#import "NSObject+Properties.h"#import <objc/runtime.h>@implementation NSObject (Properties)#pragma public - 公开方法- (void)setDataDictionary:(NSDictionary*)dataDictionary{    [self setAttributes:dataDictionary obj:self];}- (NSDictionary *)dataDictionary{    // 获取属性列表    NSArray *properties = [self propertyNames:[self class]];        // 根据属性列表获取属性值    return [self propertiesAndValuesDictionary:self properties:properties];}#pragma private - 私有方法// 通过属性名字拼凑setter方法- (SEL)getSetterSelWithAttibuteName:(NSString*)attributeName{    NSString *capital = [[attributeName substringToIndex:1] uppercaseString];    NSString *setterSelStr =     [NSString stringWithFormat:@"set%@%@:", capital, [attributeName substringFromIndex:1]];    return NSSelectorFromString(setterSelStr);}// 通过字典设置属性值- (void)setAttributes:(NSDictionary*)dataDic obj:(id)obj{    // 获取所有的key值    NSEnumerator *keyEnum = [dataDic keyEnumerator];        // 字典的key值(与Model的属性值一一对应)    id attributeName = nil;    while ((attributeName = [keyEnum nextObject]))    {        // 获取拼凑的setter方法        SEL sel = [obj getSetterSelWithAttibuteName:attributeName];                // 验证setter方法是否能回应        if ([obj respondsToSelector:sel])        {            id value      =http://www.mamicode.com/ nil;            id tmpValue   =http://www.mamicode.com/ dataDic[attributeName];                        if([tmpValue isKindOfClass:[NSNull class]])            {                // 如果是NSNull类型,则value值为空                value =http://www.mamicode.com/ nil;            }            else            {                value = tmpValue;            }                        // 执行setter方法            [obj performSelectorOnMainThread:sel                                  withObject:value                               waitUntilDone:[NSThread isMainThread]];        }    }}// 获取一个类的属性名字列表- (NSArray*)propertyNames:(Class)class{    NSMutableArray  *propertyNames = [[NSMutableArray alloc] init];    unsigned int     propertyCount = 0;    objc_property_t *properties    = class_copyPropertyList(class, &propertyCount);        for (unsigned int i = 0; i < propertyCount; ++i)    {        objc_property_t  property = properties[i];        const char      *name     = property_getName(property);                [propertyNames addObject:[NSString stringWithUTF8String:name]];    }        free(properties);        return propertyNames;}// 根据属性数组获取该属性的值- (NSDictionary*)propertiesAndValuesDictionary:(id)obj properties:(NSArray *)properties{    NSMutableDictionary *propertiesValuesDic = [NSMutableDictionary dictionary];        for (NSString *property in properties)    {        SEL getSel = NSSelectorFromString(property);                if ([obj respondsToSelector:getSel])        {            NSMethodSignature  *signature  = nil;            signature                      = [obj methodSignatureForSelector:getSel];            NSInvocation       *invocation = [NSInvocation invocationWithMethodSignature:signature];            [invocation setTarget:obj];            [invocation setSelector:getSel];            NSObject * __unsafe_unretained valueObj = nil;            [invocation invoke];            [invocation getReturnValue:&valueObj];                        //assign to @"" string            if (valueObj == nil)            {                valueObj = @"";            }                        propertiesValuesDic[property] = valueObj;        }    }        return propertiesValuesDic;}@end

测试用Model

Model.h 与 Model.m

////  Model.h//  Runtime////  Created by YouXianMing on 14-9-5.//  Copyright (c) 2014年 YouXianMing. All rights reserved.//#import <Foundation/Foundation.h>@interface Model : NSObject@property (nonatomic, strong) NSString      *name;@property (nonatomic, strong) NSNumber      *age;@property (nonatomic, strong) NSDictionary  *addressInfo;@property (nonatomic, strong) NSArray       *events;@end
////  Model.m//  Runtime////  Created by YouXianMing on 14-9-5.//  Copyright (c) 2014年 YouXianMing. All rights reserved.//#import "Model.h"@implementation Model@end

使用时的情形

////  AppDelegate.m//  Runtime////  Created by YouXianMing on 14-9-5.//  Copyright (c) 2014年 YouXianMing. All rights reserved.//#import "AppDelegate.h"#import "NSObject+Properties.h"#import "Model.h"@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    // 初始化model    Model *model = [Model new];        // 通过字典赋值    model.dataDictionary = @{@"name"        : @"YouXianMing",                             @"age"         : @26,                             @"addressInfo" : @{@"HuBei": @"WeiHan"},                             @"events"      : @[@"One", @"Two", @"Three"]};        // 打印出属性值    NSLog(@"%@", model.dataDictionary);        return YES;}@end

打印的信息:

2014-09-05 21:03:54.840 Runtime[553:60b] {

    addressInfo =     {

        HuBei = WeiHan;

    };

    age = 26;

    events =     (

        One,

        Two,

        Three

    );

    name = YouXianMing;

}

以下是两段核心代码(符合单一职能):

 

用字典给Model赋值