博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
细说KVO
阅读量:5254 次
发布时间:2019-06-14

本文共 2082 字,大约阅读时间需要 6 分钟。

1.手动控制kvo的触发 + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key; 返回NO ; 然后在改变value前 调用[object willChangeValueForKey:@"key"];
在改变value后, 调用[object didChangeValueForKey:@"key"] ; 2.隔层kvo观察

@interface Dog : NSObject

@property(nonatomic)NSInteger age;

@property(nonatomic)NSInteger *level;

@end

 

#import <Foundation/Foundation.h>

#import "Dog.h"

@interface Person : NSObject

@property(nonatomic,strong)Dog *dog;

@end

 

#import "Person.h"

 

@implementation Person

-(instancetype)init{

    self = [super init];

    if (self) {

        _dog = [[Dog alloc]init];

    }

    return self;

}

+(NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key{

    NSSet *keyPath = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"dog"]) {

        NSArray *arr = @[@"_dog.level",@"_dog.age"];

        keyPath = [keyPath setByAddingObjectsFromArray:arr];

    }

    return keyPath;

}

@end

 

 

 

//设置观察

  self.person = [[Person alloc] init];

 [self.person addObserver:self forKeyPath:@"dog" options:NSKeyValueObservingOptionOld context:nil];

 

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context

{

    NSLog(@"change:%@",change);

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event  {

    self.person.dog.age++;

}

2.KVO的底层实现

#import "NSObject+PRKVO.h"

#import <objc/runtime.h>

@implementation NSObject (PRKVO)

 

-(void)PR_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context

{

    //1.自定义一个NSKVONotifying_Person子类

    NSString *oldClassName = NSStringFromClass(self.class);

    NSString *newClassName = [@"PRKVO_" stringByAppendingString:oldClassName];

    //创建一个类

    Class MyClass = objc_allocateClassPair(self.class, newClassName.UTF8String, 0);

    //注册该类

    objc_registerProtocol(MyClass);

    

    //2.动态修改

    object_setClass(self, MyClass);

    

    //3.添加setName方法,重新父类setName

    class_addMethod(MyClass, @selector(setName:), (IMP)haha, "v@:@");

    

}

void haha(id self,SEL _cmd,NSString *newName){

    NSLog(@"!%@",newName);

}

 
 
 

转载于:https://www.cnblogs.com/PJXWang/p/8431666.html

你可能感兴趣的文章
R语言输入与输出
查看>>
国土档案管理信息系统【档案著录】-他项权利类档案著录
查看>>
P3366 【模板】最小生成树
查看>>
一个屌丝程序猿的人生(六十九)
查看>>
(二)代理模式详解(包含原理详解)
查看>>
webgame(php+flex) 的优化方案。
查看>>
Xamarin Studio –Project not built in active configuration
查看>>
Linux服务器丢包故障的解决思路及引申的TCP/IP协议栈理论
查看>>
Pandas模块
查看>>
为程序申请管理员权限
查看>>
day6——is,==,编码和解码
查看>>
mybatis学习(三)——接口式编程
查看>>
Leetcode 74 Search a 2D matrix
查看>>
JDBC工具类创建及使用
查看>>
特征归一化的方法 线性归一化 零均值归一化
查看>>
「BZOJ 2434」「NOI 2011」阿狸的打字机「AC自动机」
查看>>
Android开发学习笔记:浅谈显示Intent和隐式Intent
查看>>
繁忙的企业家
查看>>
10月30笔试题总结
查看>>
PHP Ajax 跨域问题最佳解决方案
查看>>