• 用字典给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      = nil;
                id tmpValue   = dataDic[attributeName];
                
                if([tmpValue isKindOfClass:[NSNull class]])
                {
                    // 如果是NSNull类型,则value值为空
                    value = 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;

    }

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

  • 相关阅读:
    图床_OpenStack-镜像服务
    图床_OpenStack-认证服务
    图床_OpenStack-基础环境
    #linux包之tcpdump之tcpdump命令
    利用OpenCms9提供的模块创建新站点
    Cocos2d-x3.0下实现循环列表
    Modbus读写模拟量寄存器具体解释
    C++ 实践总结
    spring Quartz基于配置文件和注解的实现
    EEPLAT学习
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3958710.html
Copyright © 2020-2023  润新知