美文网首页
iOS KVO观察者模式(坑),移除观察者removeObser

iOS KVO观察者模式(坑),移除观察者removeObser

作者: 蜂子阁先生 | 来源:发表于2018-10-26 11:33 被阅读215次

问题

在ViewDidLoad 中注册监听者 在ViewController 中dealloc 函数中调用removeObserver移除观察者发生崩溃。

代码


#import "BController.h"

@interface BController ()<UIScrollViewDelegate>

@property (nonatomic, copy) NSString *name;

@end

@implementation BController

- (void)viewDidLoad {
    [super viewDidLoad];
  
    [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

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

}

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}


@end



#import "AController.h"

@interface AController ()<UIScrollViewDelegate>

@property (nonatomic, copy) NSString *name;

@end

@implementation AController

- (void)viewDidLoad {
    [super viewDidLoad];
  
    [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

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

}

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}

- (void)testA{
     BController *bcontroller = [[BController alloc] init];
      [self.navigationController pushViewController:bcontroller animated:YES];
}

- (void)testB{
     BController *tempController = [[BController alloc] init];
 BController *controller = [[BController alloc] init];
      [self.navigationController pushViewController:controller animated:YES];
}


@end

分析

如果removeObserver 移除观察者失败,一般情况就是没有注册观察者,但是检查代码的时候发现已经在代码中注册了观察者呢???? 这是就要检查是否真正的调用了注册函数。
在AController中 testA 创建了bcontroller 控制器并跳转,显然已经调用了bcontroller中的

- (void)viewDidLoad {
    [super viewDidLoad];
  
    [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

当从bcontroller返回时调用了,移除了观察者,这是正确的运行正常

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}

但是在testB函数中,产生了奔溃

- (void)testB{
     BController *tempController = [[BController alloc] init];
     BController *controller = [[BController alloc] init];
      [self.navigationController pushViewController:controller animated:YES];
}

这是为什么呢?原来是tempController 这个控制器被创建后并没有跳转,也就是没有调用到注册函数

- (void)viewDidLoad {
    [super viewDidLoad];
  
    [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

但因为,tempController 没有任何东西引用它,意思就是tempController 这个对象创建了并没有什么用处,当执行完testB函数后会被释放并调用dealloc函数,移除观察者

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}

没有注册观察观察者,却想要移除观察者,自然产生了崩溃了🤣

相关文章

  • iOS KVO观察者模式(坑),移除观察者removeObser

    问题 在ViewDidLoad 中注册监听者 在ViewController 中dealloc 函数中调用remo...

  • iOS 如何自动移除KVO观察者

    iOS 如何自动移除KVO观察者

  • iOS KVO基础知识

    iOS KVO基础知识 1. 简介 KVO其实就对应设计模式的观察者模式,观察者能够观察其他对象(被观察者)的属性...

  • KVO原理分析

    KVO的使用 KVO使用的三部曲:添加观察者、接受回调、移除观察者;1、为什么要移除观察者呢?如果不移除会造成什么...

  • KVO与KVC

    KVO与KVC是观察者模式在iOS中的一种实现 KVO 一、KVO的介绍 KVO就是观察者模式,说白了就是你关心的...

  • KVO学习笔记

    1.KVO初探学习2.KVO 底层原理探索 1.KVO初探学习 移除观察者的重要性 (IOS11之后说不移除是不对...

  • iOS KVO

    KVO和NSNotificationCenter都是iOS中观察者模式的一种实现。区别在于,相对于被观察者和观察者...

  • 谈KVC、KVO(重点观察者模式)机制编程

    谈KVC、KVO(重点观察者模式)机制编程 谈KVC、KVO(重点观察者模式)机制编程

  • KVO & KVC

    KVO(键值观察者) 什么是KVO,KVO的实现机制是什么? KVO就是键值观察者,是观察者设计模式的实现 使用i...

  • iOS设计模式总结

    iOS常用的设计模式: KVO/通知 -------> 观察者模式 观察者模式定义了一种一对多的依赖关系,让多个观...

网友评论

      本文标题:iOS KVO观察者模式(坑),移除观察者removeObser

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