简单的KVO实现方式

作者: CoderHG | 来源:发表于2018-01-06 14:34 被阅读127次

KVO是什么?

简单地说、就是一个监听,同时也是一种设计模式。监听??那什么时候会被触发呢?具体的大家可以参考我的上一篇介绍:KVO与Category,主要介绍了KVO的简单使用以及在Category中动态添加成员变量实现KVO监听。其中也介绍了,被注册监听的字段被触发KVO的条件是必须调用setter方法。

KVO实现

创建一个干净的Class,名叫SimpleObject
.h文件是这样的:


#import <Foundation/Foundation.h>

// KVO 回调
typedef void(^KVOBlock)(id oldValue, id newValue);

@interface SimpleObject : NSObject

/** 属性 */
@property (nonatomic, copy) NSString* hgName;

/**
 史上最简单的KVO监听方法

 @param keyPath keyPath
 @param kvoBlock 回调
 */
- (void)addKVOforKeyPath:(NSString*)keyPath kvoBlock:(KVOBlock)kvoBlock;

@end

一个辅助Class:


@interface Path8KVOBlockObject : NSObject

/** 被监听的 keyPath */
@property (nonatomic, copy) NSString* keyPath;
/** 被监听的 回调 */
@property (nonatomic, copy) KVOBlock  kvoBlock;

@end

@implementation Path8KVOBlockObject

@end

先来看看的监听方法的实现:

/**
史上最简单的KVO监听方法

@param keyPath keyPath
@param kvoBlock 回调
*/
- (void)addKVOforKeyPath:(NSString*)keyPath kvoBlock:(KVOBlock)kvoBlock {
   if (!keyPath || !kvoBlock) {
       return;
   }
   // 初始化 _keyPath8KVOBlockArrM
   if (!_keyPath8KVOBlockArrM) {
       _keyPath8KVOBlockArrM = [NSMutableArray array];
   }
   
   // 获取
   Path8KVOBlockObject* pbObject = [self pbObjectForKeyPath:keyPath];
   if (!pbObject) {
       // 没有就重新创建
       pbObject = [[Path8KVOBlockObject alloc] init];
       [_keyPath8KVOBlockArrM addObject:pbObject];
   }
   // 赋值
   pbObject.keyPath = keyPath;
   pbObject.kvoBlock = kvoBlock;
   
}

这个方法的功能类似与系统的这个方法:addObserver: forKeyPath: options: context:

重写被监听的setter方法:


- (void)setHgName:(NSString *)hgName {
    // 保留旧值
    NSString* oldValue = _hgName;
    // 赋值
    _hgName = hgName.copy;
    
    // 找到对应的监听, 然后执行
    Path8KVOBlockObject* pbObject = [self pbObjectForKeyPath:@"hgName"];
    if (pbObject.kvoBlock) {
        pbObject.kvoBlock(oldValue, _hgName);
    }
}

这样,一个最简单的KVO实现就是OK了, 没有运行时,也没有Runloop。实验时这样的:


image.png

用法, 比系统的KVO还要简单。

但是,一定要主要指针循环:


image.png

其它

正常情况下,监听之后是这个样子的:


image.png

但是,如果做了如下处理的话。


image.png

结果就是这个样子的:


image.png

意思是没有改变isa指针。

在这种情况下就不会有KVO效果了。但是, 可以这么弄:


image.png

这样就可以了, 突然脑补了一下, 把这条代码注释了, 可否:


image.png

答案、肯定是不可以的,不信你把代码代码代码下载下来试试。

谢谢~

相关文章

  • 简单的KVO实现方式

    KVO是什么? 简单地说、就是一个监听,同时也是一种设计模式。监听??那什么时候会被触发呢?具体的大家可以参考我的...

  • iOS探索KVO实现原理,重写KVO

    写响应式编程博客时,提到了KVO,今天我们探索一下KVO的实现原理及如何自己实现KVO功能 首先简单的KVO实现 ...

  • 2016笔记——KVO

    记得KVO是最早接触的属性与方法相关联的实现方式,也是最简单的方法。 究竟KVO是如何实现的呢? 探究一番: 猜猜...

  • KVO 解析

    KVO解析(一) —— 基本了解KVO解析(二) —— 一个简单的KVO实现KVO解析(三) —— KVO合规性K...

  • iOS中你可能没有完全弄清楚的(二)自己实现一个KVO源码及解析

    前几天写了一篇blog(点这里),分析了系统KVO可能的实现方式。并添加了简单代码验证。 既然系统KVO不好用,我...

  • iOS - 自定义KVO

    之前我们已经了解过了KVO的底层实现原理,不过呢,在我们开始实现自定义KVO之前再来简单回顾下KVO的实现原理 1...

  • KVO

    KVO (Key-value-observing) 键值监听 iOS用什么方式实现对一个对象的KVO?(KVO的本...

  • IOS基础知识-KVO原理篇

    问题 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)如何手动触发KVO KVO的全称 Key-V...

  • iOS底层原理汇 - 探索KVO本质

    问题 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) 如何手动触发KVO ? 首先需要了解KVO...

  • KVO和KVC的本质

    一、KVO 问题 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) 如何手动触发KVO? 1. K...

网友评论

    本文标题:简单的KVO实现方式

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