美文网首页
iOS KVC & KVO

iOS KVC & KVO

作者: SnoopPanda | 来源:发表于2020-05-11 16:46 被阅读0次
KVC

KVC全称Key-Value Coding,俗称“键值编码”,可以通过Key来访问某个属性,写在NSObject的NSKeyValueCoding分类下面。

常用方法
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (nullable id)valueForKey:(NSString *)key;
- (nullable id)valueForKeyPath:(NSString *)keyPath;

setValue:forKey:的原理

image.png

valueForKey:的原理

image.png
使用场景

1.使用KVC访问修改私有变量、内部属性
2.字典模型转换
tips: KVC在使用中最常见的异常是使用了错误的key,或者传了nil。第一种情况重写setValue: forUndefinedKey:可以避免crash,第二种情况重写setNilValueForKey:

KVO

KVO全程Key-Value Observing,俗称“键值观察”。

常用方法
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;
实现原理
image.png
Person *p = [Person new];
NSLog(@"person添加KVO之前 - person:%@",object_getClass(p));
[p addObserver:self forKeyPath:@"age" options: NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld context:nil];
NSLog(@"person添加KVO之后 - person:%@",object_getClass(p));

// 2020-05-11 16:32:37.834314+0800 KVO[81741:2296042] person添加KVO之前 - person:Person
// 2020-05-11 16:32:37.834575+0800 KVO[81741:2296042] person添加KVO之后 - person:NSKVONotifying_Person
  • 在运行时,系统会为调用addObserver: forKeyPath: options: context:方法的类,动态派生出一个名字是NSKVONotifying_xxx的子类,例如:Person 添加了观察者以后,动态派生出了NSKVONotifying_Person子类。

  • 在子类中,重写了对应Key的set方法,为代码如下

    - (void)setAge:(int)age
    {
        _NSSetIntValueAndNotify();
    }
    
    // 伪代码
    void _NSSetIntValueAndNotify()
    {
        [self willChangeValueForKey:@"age"];
        [super setAge:age];
        [self didChangeValueForKey:@"age"];
    }
    
    - (void)didChangeValueForKey:(NSString *)key
    {
        // 通知监听器,某某属性值发生了改变
      [oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
    }
    
  • 重写了class方法,通过class方法直接返回person,不然就返回NSKVONotifying_Person

  • 重写了dealloc方法,类释放的时候,做一些清楚释放操作

  • 增加了-isKVOA方法,返回YES,则使用KVO

    - (void)printMethodNamesOfClass:(Class)cls
    {
        unsigned int count;
        // 获得方法数组
        Method *methodList = class_copyMethodList(cls, &count);
      
        // 存储方法名
        NSMutableString *methodNames = [NSMutableString string];
      
        // 遍历所有的方法
        for (int i = 0; i < count; i++) {
            // 获得方法
            Method method = methodList[i];
            // 获得方法名
            NSString *methodName = NSStringFromSelector(method_getName(method));
            // 拼接方法名
            [methodNames appendString:methodName];
            [methodNames appendString:@", "];
        }
      
        // 释放
        free(methodList);
      
        // 打印方法名
        NSLog(@"%@ %@", cls, methodNames);
    }
    //输出
    2019-12-29 21:21:04.068859+0800 Interview01[11719:1127666] NSKVONotifying_Person setAge:, class, dealloc, _isKVOA,
    
tips:

1.手动调用willChangeValueForKey:和didChangeValueForKey:会触发KVO
2.直接修改成员变量不会触发KVO,通过KVC给属性设置值如果调用了set方法就会触发KVO

相关文章

  • KVC 和 KVO

    iOS-KVC和KVO精炼讲解(干货)KVC 和 KVOiOS开发系列--Objective-C之KVC、KVO细...

  • KVC

    iOS 如何使用KVC iOS开发UI篇—Kvc简单介绍 iOS开发系列--Objective-C之KVC、KVO

  • iOS - KVO

    [toc] 参考 KVO KVC 【 iOS--KVO的实现原理与具体应用 】 【 IOS-详解KVO底层实现 】...

  • iOS-KVO浅谈

    上一篇:iOS-KVC浅谈 前言:KVO 作为 KVC 的同袍兄弟,功能更强大,聊聊 KVO。 一、KVO 简介 ...

  • iOS日记15-KVC

    1.iOS开发技巧系列---详解KVC 2.漫谈 KVC 与 KVO 3.KVC/KVO原理详解及编程指南 关键点...

  • iOS面试题:KVC的赋值和取值过程是怎样的?KVO原理是什么?

    更多:iOS面试题大全 1、KVC赋值 2、 KVC取值 3、 KVO原理 KVO 是 Objective-C 对...

  • iOS原理(二)----KVO,KVC

    iOS原理(二)----KVO,KVC KVO KVO的全称是Key-Value Observing,俗称“键值监...

  • 从网上收集的一些关键知识点总结

    iOS 中KVC、KVO、NSNotification、delegate 总结及区别

  • 知识点3

    26. 什么是KVC和KVO? KVO: iOS开发-KVO的奥秘 http://www.jianshu.com/...

  • 无标题文章

    ios中的 kvc和kvo的区别 KVC编程时setValue(value: AnyObje...

网友评论

      本文标题:iOS KVC & KVO

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