1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| - (void)yc_setValue:(nullable id)value forKey:(NSString *)key { if (key == nil || key.length == 0) { return; } NSString *Key = key.capitalizedString; //首字母大写 // 拼接相关的方法名 NSString *setKey = [NSString stringWithFormat:@"set%@:",Key]; NSString *_setKey = [NSString stringWithFormat:@"_set%@:",Key]; NSString *setIsKey = [NSString stringWithFormat:@"setIs%@:",Key];
// 按顺序判断是否实现三个实例方法 if ([self yc_performSelectorWithMethodName:setKey value:value]) { NSLog(@"___ %@ ___",setKey); return; } else if ([self yc_performSelectorWithMethodName:_setKey value:value]) { NSLog(@"___ %@ ___",_setKey); return; } else if ([self yc_performSelectorWithMethodName:setIsKey value:value]) { NSLog(@"___ %@ ___",setIsKey); return; }
if (![self.class accessInstanceVariablesDirectly] ) { @throw [NSException exceptionWithName:@"yc_UnknownKeyException" reason:[NSString stringWithFormat:@"****[%@ valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.****",self] userInfo:nil]; }
// 获取所有实例变量的名字 NSMutableArray *mArray = [self getIvarListName]; // 拼接出需要的实例变量名字 NSString *_key = [NSString stringWithFormat:@"_%@",key]; NSString *_isKey = [NSString stringWithFormat:@"_is%@",Key]; NSString *isKey = [NSString stringWithFormat:@"is%@",Key];
// 依次判断拼接的实例变量名字是否在实例变量数组中,存在则获取实例变量并赋值 if ([mArray containsObject:_key]) { Ivar ivar = class_getInstanceVariable([self class], _key.UTF8String); object_setIvar(self , ivar, value); return; } else if ([mArray containsObject:_isKey]) { Ivar ivar = class_getInstanceVariable([self class], _isKey.UTF8String); object_setIvar(self , ivar, value); return; } else if ([mArray containsObject:key]) { Ivar ivar = class_getInstanceVariable([self class], key.UTF8String); object_setIvar(self , ivar, value); return; } else if ([mArray containsObject:isKey]) { Ivar ivar = class_getInstanceVariable([self class], isKey.UTF8String); object_setIvar(self , ivar, value); return; }
// 如果找不到相关实例变量,就抛出异常 @throw [NSException exceptionWithName:@"yc_UnknownKeyException" reason:[NSString stringWithFormat:@"****[%@ %@]: this class is not key value coding-compliant for the key name.****",self, NSStringFromSelector(_cmd)] userInfo:nil]; }
- (BOOL)yc_performSelectorWithMethodName:(NSString *)methodName value:(id)value{ // 判断方法是否能响应, if ([self respondsToSelector:NSSelectorFromString(methodName)]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" // 能响应则调用 [self performSelector:NSSelectorFromString(methodName) withObject:value]; #pragma clang diagnostic pop return YES; } return NO; }
// 获取实例变量的名字 - (NSMutableArray *)getIvarListName{ NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:1]; unsigned int count = 0; Ivar *ivars = class_copyIvarList([self class], &count); for (int i = 0; i<count; i++) { Ivar ivar = ivars[i]; const char *ivarNameChar = ivar_getName(ivar); NSString *ivarName = [NSString stringWithUTF8String:ivarNameChar]; NSLog(@"ivarName == %@",ivarName); [mArray addObject:ivarName]; } free(ivars); return mArray; }
|