/**
* 给对象赋值
*
* @param obj 任意对象
* @param paramers 传入的参数,参数名需要和obj对象属性同名
*/
- (void)setProptyWithObject:(id)obj paramers:(NSDictionary *)paramers
{
const char *className = object_getClassName(obj);
id creditorDetail = objc_getClass(className);
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(creditorDetail, &outCount);
for (NSString *parm in paramers) {
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
NSString *propName = [NSString stringWithUTF8String:property_getName(property)];
if ([propName isEqualToString:parm]) {
const char *p_type_str = property_getAttributes(property);
NSString *attrTypeStrS = [NSString stringWithUTF8String:p_type_str];
NSArray *attrArray = [attrTypeStrS componentsSeparatedByString:@","];
NSString *attrTypeStr = attrArray[0];
const char *p_type = [[attrTypeStr substringFromIndex:1] UTF8String];
if (!strcmp(p_type, @encode(BOOL))) {
NSNumber *number = [NSNumber numberWithBool:[((NSString *)paramers[propName])boolValue]];
[obj setValue:number forKey:propName];
}
else if (!strcmp(p_type, @encode(NSInteger)) || !strcmp(p_type, @encode(NSUInteger))) {
NSNumber *number = [NSNumber numberWithInteger:[((NSString *)paramers[propName])integerValue]];
[obj setValue:number forKey:propName];
}
else if ([attrTypeStrS containsSubstring:@"NSString"]) {
[obj setValue:paramers[propName] forKey:propName];
}
else if (!strcmp(p_type, @encode(double))) {
NSNumber *number = [NSNumber numberWithDouble:[((NSString *)paramers[propName])doubleValue]];
[obj setValue:number forKey:propName];
}
else if (!strcmp(p_type, @encode(float))) {
NSNumber *number = [NSNumber numberWithFloat:[((NSString *)paramers[propName])floatValue]];
[obj setValue:number forKey:propName];
}
else if ([attrTypeStrS containsSubstring:@"NSNumber"]) {
NSNumberFormatter *numFormat = [[NSNumberFormatter alloc] init];
numFormat.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *number = [numFormat numberFromString:(NSString *)paramers[propName]];
[obj setValue:number forKey:propName];
}
else { //目前只能处理BOOL,NSInteger,NSUInteger,CGFloat,NSString,NSNumber类型,其他类型不能处理
NSAssert(0, @"not support");
}
}
}
}
}
问题描述:类中存在BOOL属性、iPhone5(包括5)之前的设备crash。
原因:iPhone5之后,为32bit系统,BOOL用signed char 类型表示,64bit用bool类型表示。在使用kvc的时候,系统将NSString类型转化成signed char时没有对应方法导致crash。
解决方法:可以将类中BOOL类型参数改成NSString或者NSInteger类型。
update:2016.07.13
该问题还存在于NSInteger,NSUInteger,CGFloat等,给controller赋值的时候,基于runtime自己写了个方法如下: