美文网首页iOS底层基础知识iOS面试知识点
iOS-底层原理(5)-KVC底层原理详解

iOS-底层原理(5)-KVC底层原理详解

作者: 路飞_Luck | 来源:发表于2018-08-26 16:22 被阅读112次
    面试题
    1. 通过KVC修改属性会触发KVO么?
    • 会触发KVO

    代码例子佐证

    @interface Person : NSObject
    @property (assign, nonatomic) int age;
    @end
    
    @interface Observer : NSObject
    @end
    @implementation Observer
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
        NSLog(@"observeValueForKeyPath - %@", change);
    }
    @end
    
    #import <Foundation/Foundation.h>
    #import "Person.h"
    #import "Observer.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            Observer *observer = [[Observer alloc] init];
            Person *person = [[Person alloc] init];
            
            // 添加KVO监听
            [person addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
            
            // 通过KVC修改age属性
            [person setValue:@10 forKey:@"age"];
            
            // 移除KVO监听
            [person removeObserver:observer forKeyPath:@"age"];
        }
        return 0;
    }
    

    运行结果

    KVC.png
    2. KVC的赋值和取值过程是怎样的?原理是什么?
    • 详情见下文的valueForKey:的原理图
    序言

    KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性

    • 常见的API有
      • -(void)setValue:(id)value forKeyPath:(NSString *)keyPath;
      • -(void)setValue:(id)value forKey:(NSString *)key;
      • -(id)valueForKeyPath:(NSString *)keyPath;
      • -(id)valueForKey:(NSString *)key;
    setValue:forKey:的原理
    image.png

    代码例子佐证

    • accessInstanceVariablesDirectly返回NO
    // 默认的返回值就是YES
    + (BOOL)accessInstanceVariablesDirectly {
        return NO;
    }
    
    image.png
    • accessInstanceVariablesDirectly返回YES,并且有下划线成员变量
    @interface Person : NSObject {
    @public
        int age;
        int isAge;
        int _isAge;
        int _age;
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            Person *person = [[Person alloc] init];
            // 通过KVC修改age属性
            [person setValue:@10 forKey:@"age"];
            
            NSLog(@"%@", [person valueForKey:@"age"]);
        }
        return 0;
    }
    

    运行结果

    image.png

    可以将变量依次注释,看看打印结果ageisAge_isAge_age

    @public
        int age;
        int isAge;
    //    int _isAge;
    //    int _age;
    }
    

    运行结果

    image.png
    valueForKey:的原理
    valueForKey.png
    • 代码例子佐证 - 先找方法
    @implementation Person
    
    // 第一顺序调用
    - (int)getAge {
        return 11;
    }
    
    // 第二顺序调用
    - (int)age {
        return 12;
    }
    
    // 第三顺序调用
    - (int)isAge {
        return 13;
    }
    
    // 第四顺序调用
    - (int)_age {
        return 14;
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            Person *person = [[Person alloc] init];
    
            NSLog(@"%@", [person valueForKey:@"age"]);
        }
        return 0;
    }
    
    • 依次注释掉方法getAgeageisAge_age,然后打印结果如下
    getAge.png age.png isAge.png _age.png
    • 代码例子佐证 - 再找成员变量
    @interface Person : NSObject {
    @public
        int age;
        int isAge;
        int _isAge;
        int _age;
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            Person *person = [[Person alloc] init];
            // 通过KVC修改age属性
            person->_age = 100;
            person->_isAge = 110;
            person->age = 120;
            person->isAge = 130;
            
            NSLog(@"%@", [person valueForKey:@"age"]);
        }
        return 0;
    }
    
    • 依次在Person.h文件中注释成员变量_age_isAgeageisAge,然后查看打印结果
    _age.png _isAge.png age.png isAge.png

    如果将方法和成员变量全部去掉,打印结果如下

    image.png

    由打印结果可知,如果方法和成员变量都找不到,则最终方法找不到的错误。


    本文参考借鉴MJ的教程视频,非常感谢.


    项目连接地址 - iOS-KVC

    相关文章

      网友评论

        本文标题:iOS-底层原理(5)-KVC底层原理详解

        本文链接:https://www.haomeiwen.com/subject/tgeoiftx.html