美文网首页
iOS 深入了解KVO 本质/使用

iOS 深入了解KVO 本质/使用

作者: iOS刘耀宗 | 来源:发表于2021-06-20 12:43 被阅读0次

项目 Demo 下载
解决的问题:
1:iOS KVO的本质
2: 如何手动触发 KVO

KVO:键值监听. 监听某个对象属性值的改变
第一步: 对象监听属性的改变

[self.model addObserver:self forKeyPath:@"name" options: NSKeyValueObservingOptionNew context:nil];

第二步: 添加对象属性改变的回调方法

//回调
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"change = %@",change);
    }
    NSLog(@"监听到了 OC");
}
oc版
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor yellowColor];
    // Do any additional setup after loading the view.
    self.model = [KVOModel new];
    //添加观察者
    [self.model addObserver:self forKeyPath:@"name" options: NSKeyValueObservingOptionNew context:nil];
    self.model.name = @"adsf ";
    NSLog(@"name = %@",self.model.name);
}

//回调
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"change = %@",change);
    }
    NSLog(@"监听到了 OC");
}

//销毁的时候一定要移除
-(void)dealloc
{
    [self.model removeObserver:self forKeyPath:@"name"];
}

关键点:

//未被监听前
(lldb) po self.model.isa
KVOModel

  Fix-it applied, fixed expression was: 
    self.model->isa
//监听后
(lldb) po self.model.isa
NSKVONotifying_KVOModel

  Fix-it applied, fixed expression was: 
    self.model->isa
(lldb) 

通过上面我们可以发现. 当 model 被监听后,它的 isa 指针指向了另外一个类.是 model 类的子类->NSKVONotifying_KVOModel .它是通过 runtime 动态创建的一个类
通过新建的类 调用 setName 的方法会触发下面两个方法
1:willChangeValueForKey
2:didChangeValueForKey
通过上面的方法来达到回调. 这也就是为什么,监听了之后会触发回调方法的实现

同时: 如果想要手动触发 KVO. 那么调用上面两个方法即可手动触发

[self.model willChangeValueForKey:@"name"];
[self.model didChangeValueForKey:@"name"];
swift 版本

跟 oc 版一样大致一样. 但是有一点需要注意
需要监听的属性需要加上 @objc dynamic 表示创建一个被观察的对象

class Person: NSObject {
    @objc dynamic var name = "张三"
    var age = 10
}

代码:

class ViewController: UIViewController {

    let person = Person()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
        // Do any additional setup after loading the view.
        person.addObserver(self, forKeyPath: "name", options: [NSKeyValueObservingOptions.new,NSKeyValueObservingOptions.old], context: nil)
        print(person.name)
        
        let jumpBtn = UIButton()
        jumpBtn.setTitle("OC 版本", for: .normal)
        jumpBtn.addTarget(self, action: #selector(click), for: .touchUpInside)
        view.addSubview(jumpBtn)
        jumpBtn.frame = .init(x: 200, y: 200, width: 200, height: 20)

    }
    
    @objc func click() {
        let vc = OCKvoViewController()
        present(vc, animated: true, completion: nil)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("\(person.name)")
        person.name = "张三改"
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("监听到了")
    }

    
    deinit {
        person.removeObserver(self, forKeyPath: "name", context: nil)
    }

}

class Person: NSObject {
    @objc dynamic var name = "张三"
    var age = 10
}

相关文章

  • iOS 深入了解KVO 本质/使用

    项目 Demo 下载[https://github.com/liuyaozong1/LYZKVODemo.git]...

  • iOS底层原理总结 - 探寻KVO本质

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

  • Objective-C的本质(4)—— KVO本质

    参考:iOS底层原理总结 - 探寻KVO本质iOS-KVO本质 问题一:kvo如果找到对应的属性 KVO不存在查找...

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

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

  • KVO

    iOS用什么方式实现对一个对象的KVO?(KVO的本质) 1 未使用KVO监听的对象 MJPerson insta...

  • 通过面试题来剖析KVO以及KVC

    iOS用什么方式实现对一个对象的KVO?(KVO的本质?) NSKVONotifying_MJPerson是使用R...

  • iOS开发-底层原理 - KVO

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

  • KVO

    基本使用 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)KVO的全称是Key-Value Obs...

  • 深入理解KVO

    iOS | KVO | Objective-C KVO的本质是什么,如何手动触发KVO? 1.什么是KVO KVO...

  • iOS-KVO(二) 使用注意点

    iOS-KVO(一) 基本操作iOS-KVO(二) 使用注意点iOS-KVO(三) 窥探底层实现iOS-KVO(四...

网友评论

      本文标题:iOS 深入了解KVO 本质/使用

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