zoukankan      html  css  js  c++  java
  • 重写KVC

    #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
  • 相关阅读:
    Linux密码文件介绍
    MongoDB与微服务
    MongoDB应用场景及选型
    MongoDB性能诊断工具
    1.7每日进度
    《架构即未来》(3)
    《架构即未来》(2)
    论面向服务架构设计
    浅谈MVC设计模式
    《架构即未来》(1)
  • 原文地址:https://www.cnblogs.com/liuwenqiang/p/8536614.html
Copyright © 2011-2022 走看看