IOS开发 模型赋值 runtime

#import "CZJsonObject.h"
#import <objC/runtime.h>
#import <objc/message.h>


NSString *setter_from_key(NSString *key)
{
    //capitalise the first letter
    NSString *setter = [key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[key substringToIndex:1] uppercaseString]];
    //add 'set' and the colon
    setter = [NSString stringWithFormat:@"set%@:", setter];
    return setter;
}

@implementation CZJsonObject

- (void)fitNilInproperty
{
    Class _targetClass = [self class];
    while ([_targetClass class]!=[NSObject class]) {
        [self fitNibWithClass:_targetClass];
        _targetClass = [_targetClass superclass];
    }
}
/*
 * @waring 对于自定义getter和/或setter方法名的属性无效
 */
- (void)fitNibWithClass:(Class)class
{
    //传出参数,获取属性的数量
    unsigned int outCount = 0;
    //获取属性列表的副本(所指向的指针)
    objc_property_t* ptable  = class_copyPropertyList(class, &outCount);//执行后outCount等于类的属性数量
    //备份列表指针,便于最后释放
    objc_property_t* ptable_first = ptable;
    //遍历属性列表
    for (unsigned int index = 0; index<outCount; index++) {
        //获取 当前属性的@encode
        const char* attrName = property_getAttributes(*ptable);
        NSString* attrNameStr = [NSString stringWithCString:attrName encoding:NSUTF8StringEncoding];
        //判断当前属性类型是否为对象
        //若@encode以@T开头,则为id型(近似但不等于对象)
        //若@encode以@T开头,而且匹配[".+"],则意味着属性为自定义对象类型(NS类包含在内)
        if (([attrNameStr hasPrefix:@"T@"]) && ([attrNameStr rangeOfString:@"".+"" options:NSRegularExpressionSearch].location!=NSNotFound)) {
            //获取当前属性 的 属性名
            const char* propertyCName = property_getName(*ptable);
            NSString* propertyName = [NSString stringWithCString:propertyCName encoding:NSUTF8StringEncoding];
            //获取getter的方法名
            NSString* getterName = propertyName;
            //检查该getter是否存在,若getter被自定义,则getter名不等于属性名
            BOOL isDefaultGetter = [self respondsToSelector:NSSelectorFromString(getterName)];
            if (isDefaultGetter) {
                //调用该属性的getter,获取属性值
                NSObject* propertyValue = [self performSelector:NSSelectorFromString(getterName)];
                //当属性值为nil

           if (propertyValue==nil||propertyValue==[NSNull null]||propertyValue==NULL) {

                    //从@encode分离类型信息

                    NSArray* attrArr = [attrNameStr componentsSeparatedByString:@"""];

                    //取出属性类型名

                    NSString* propertyTypeClassName = [attrArr objectAtIndex:1];

                    //根据类型名获取默认值

                    NSObject* defaultValue = [self defaultValueWithClassType:propertyTypeClassName];

                    //同上,检查该getter是否为默认的setter

                    BOOL isDefaultSetter = [self respondsToSelector:NSSelectorFromString(setter_from_key(propertyName))];

                    if (isDefaultSetter) {

                        //调用setter,将默认值传人

                        [self performSelector:NSSelectorFromString(setter_from_key(propertyName)) withObject:defaultValue];

                    }

                }

            }

        }


        //列表偏移到下一位属性
        ptable++;
    }
    //遍历完成后,释放属性列表副本
    free(ptable_first);
}

- (id)defaultValueWithClassType:(NSString*)type
{
    id result = [[NSObject alloc]init];
    if ([type hasPrefix:@"NS"]) {
        if ([type isEqualToString:@"NSString"]) {
            result = @"";//[[NSString alloc]init];
        }else if ([type isEqualToString:@"NSNumber"]) {
            result = @0;//[[NSNumber alloc]init];
        }else if ([type isEqualToString:@"NSDictionary"]) {
            result = [[NSDictionary alloc]init];
        }else if ([type isEqualToString:@"NSArray"]) {
            result = [[NSArray alloc]init];
        }else if ([type isEqualToString:@"NSMutableDictionary"]) {
            result = [[NSMutableDictionary alloc]initWithCapacity:1];
        }else if ([type isEqualToString:@"NSMutableArray"]) {
            result = [[NSMutableArray alloc]initWithCapacity:1];
        }else if ([type isEqualToString:@"NSDate"]) {
            result = [[NSDate alloc]initWithTimeIntervalSince1970:0];
        }else if ([type isEqualToString:@"NSData"]) {
            result = [[NSData alloc]initWithBase64EncodedString:@" " options:NSDataBase64DecodingIgnoreUnknownCharacters];
        }
    }
    return result;
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {
        _theId = value;
    }else if([key isEqualToString:@"description"]){
        _theDescription = value;
    }else{
        //NSLog(@"%@ underfine the property: @property(nonatomic,readwrite) %@ %@; = %@",[self class],[value class],key,value);
    }
}
原文地址:https://www.cnblogs.com/mojiewei/p/5651373.html