简单的KVO实现方式

KVO是什么?

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

KVO实现

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


#import 

// 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。实验时这样的:


简单的KVO实现方式_第1张图片
image.png

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

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


简单的KVO实现方式_第2张图片
image.png

其它

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


简单的KVO实现方式_第3张图片
image.png

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


简单的KVO实现方式_第4张图片
image.png

结果就是这个样子的:


简单的KVO实现方式_第5张图片
image.png

意思是没有改变isa指针。

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


简单的KVO实现方式_第6张图片
image.png

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


image.png

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

谢谢~

你可能感兴趣的:(简单的KVO实现方式)