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