#import "NSObject+WQKVC.h"
#import <objc/runtime.h>
/**
KVC
首先调用的方法顺序:
|- setter: setKey -> setIsKey
|- getter: getKey -> key -> isKey
|- - (Bool)accessInstanceVariablesDirectly 不为NO ,默认为YES
查找成员变量的顺序:
|- _key -> _isKey -> key -> isKey
**/
@implementation NSObject (WQKVC)
- (void)WQ_setValue:(id)value forKey:(NSString *)key
{
//判断key的合法性
if (key.length == 0 || key == nil) {
return;
}
NSString *setKey = [NSString stringWithFormat:@"set%@",key.capitalizedString];
SEL setKeyMethod = NSSelectorFromString(setKey);
if ([self respondsToSelector:setKeyMethod]) {
[self performSelector:setKeyMethod withObject:value];
return;
}
NSString *setIsKey = [NSString stringWithFormat:@"setIs%@",key.capitalizedString];
SEL setIsKeyMethod = NSSelectorFromString(setIsKey);
if ([self respondsToSelector:setIsKeyMethod]) {
[self performSelector:setIsKeyMethod withObject:value];
return;
}
if (![self.class accessInstanceVariablesDirectly]) {
NSException *exception = [NSException exceptionWithName:@"WQKVC Exception" reason:@"不能设置为NO!" userInfo:nil];
@throw exception;
return;
}
unsigned int count = 0;
Ivar *ivasList = class_copyIvarList([self class], &count);
// _Key
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_%@",key.capitalizedString]]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
}
// _isKey
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_is%@",key.capitalizedString]]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
}
// Key
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:key]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
}
// isKey
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"is%@",key.capitalizedString]]) {
object_setIvar(self, ivasList[i], value);
free(ivasList);
return;
}
}
// 异常处理!
[self setValue:value forUndefinedKey:key];
free(ivasList);
}
- (id)WQ_valueForKey:(NSString *)key
{
if (key.length == 0 || key == nil) {
return nil;
}
// getKey -- Method
NSString *getKey = [NSString stringWithFormat:@"get%@",key.capitalizedString];
SEL getKeyMethod = NSSelectorFromString(getKey);
if ([self respondsToSelector:getKeyMethod]) {
return [self performSelector:getKeyMethod withObject:nil];
}
// key -- Method
SEL KeyMethod = NSSelectorFromString(key);
if ([self respondsToSelector:getKeyMethod]) {
return [self performSelector:KeyMethod withObject:nil];
}
// isKey -- Method
NSString *isKey = [NSString stringWithFormat:@"is%@",key.capitalizedString];
SEL isKeyMethod = NSSelectorFromString(isKey);
if ([self respondsToSelector:isKeyMethod]) {
return [self performSelector:isKeyMethod withObject:nil];
}
if (![self.class accessInstanceVariablesDirectly]) {
NSException *exception = [NSException exceptionWithName:@"WQKVC Exception" reason:@"不能设置为NO!" userInfo:nil];
@throw exception;
return nil;
}
unsigned int count = 0;
Ivar *ivasList = class_copyIvarList([self class], &count);
// _Key
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_%@",key.capitalizedString]]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
}
// _isKey
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"_is%@",key.capitalizedString]]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
}
// Key
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:key]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
}
// isKey
for (int i = 0; i < count ; i ++) {
NSString *keyStr = [NSString stringWithUTF8String:ivar_getName(ivasList[i])];
if ([keyStr isEqualToString:[NSString stringWithFormat:@"is%@",key.capitalizedString]]) {
Ivar ivar_temp = ivasList[i];
free(ivasList);
return object_getIvar(self, ivar_temp);
}
}
free(ivasList);
return [self valueForUndefinedKey:key];
}
@end