码迷,mamicode.com
首页 > 其他好文 > 详细

重写KVC

时间:2018-03-10 00:15:03      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:forms   res   nsstring   顺序   cap   ble   ali   成员变量   eth   

#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

 

重写KVC

标签:forms   res   nsstring   顺序   cap   ble   ali   成员变量   eth   

原文地址:https://www.cnblogs.com/liuwenqiang/p/8536614.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!