KVO等具体实现步骤以及注意事项
KVO是一种设计模式,名为观察者.
addObserver:forKeyPath:options:context:
通知其他对象的方法,这个方法在NSObject中就已经申明了,也就是说任何继承自NSObject的对象都可以使用KVO.
我们来实现一个对象a值改变的时候去通知对象b.
新建两个ModelA ModelB 类.
ModelA.h + ModelA.m

#import <Foundation/Foundation.h> @interface ModelA : NSObject @property (nonatomic, strong) NSString *name; @end

#import "ModelA.h" @implementation ModelA @end
ModelB.h + ModelB.m

#import <Foundation/Foundation.h> @interface ModelB : NSObject @property (nonatomic, strong) NSString *sex; @end


#import "ModelB.h" @implementation ModelB -(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
self.sex = @"female";
} @end

请将如下延时执行的代码添加进工程当中
- (void)delay:(int64_t)delta execute:(dispatch_block_t)block
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta * NSEC_PER_SEC),
dispatch_get_main_queue(), block);
}
然后再写如下的代码:
执行结果如下:
2014-05-06 17:40:35.346 FileManager[20208:60b] Application windows are expected to have a root view controller at the end of application launch
2014-05-06 17:40:37.347 FileManager[20208:60b] female
如果注释掉ModelB中的方法observeValueForKeyPath:ofObject:change:context:,运行时会导致崩溃:
如果重复移除了两次,也会导致崩溃-_-!!!!
也就是这么一层关系:
A对象要通知B对象,B对象必须实现监听的方法,否则一旦有消息发送就会导致崩溃.
A对象不想通知B对象了,需要从B对象身上移除掉通知.
要想程序不出现问题,我们需要实现3步.
(主动添加B的通知) A -------> B(不实现一个方法就崩溃)
(主动移除B的通知) A ---X--> B
(重复移除B的通知) A ---X--> B(崩溃)
用起来很恶性,还好,我们可以重复添加B的通知而不崩溃......
问题:在ARC中我们需要移除KVO的observer么?
You should explicitly remove the observer even you use ARC
. Create a dealloc
method and remove there..
-(void)dealloc {[[NSNotificationCenter defaultCenter] removeObserver:self];}
If you see the method you don't need to call [super dealloc];
here, only the method without super dealloc needed.
你需要非常明确的移除你的通知者,即使是在ARC中.创建一个dealloc
方法然后在方法里面移除.
ARC中你不需要调用[super dealloc].
问题:ARC给一个对象添加了observer有可能会导致循环应用什么的么?
You need to call removeObserver
, ARC only automates retain counts. removeObserver
does not impact the retain count.
你需要调用removeObserver
,ARC只是自动管理了retain counts,removeObserver
并不影响retain count.(这一点我不确定,有待验证)
问题:当要通知的对象已经nil了,这个通知会自动移除吗?
Observers are not removed automatically. From the NSNotificationCenter Class Reference:
观察者不会自动移除,请查看NSNotificationCenter类的原文引述:
Important: The notification center does not retain its observers, therefore, you must ensure that you unregister observers (using removeObserver: or removeObserver:name:object:) before they are deallocated. (If you don't, you will generate a runtime error if the center sends a message to a freed object.)
很重要:通知中心并不会retain他的观察者,所以,你必须确保你那些对象销毁之前注销掉观察者,否则就会出现错误.
You should therefore call
[[NSNotificationCenter defaultCenter] removeObserver:self];
in your dealloc
method if you are not 100% sure that the observer was not removed previously.
addObserver:forKeyPath:options:context:
Registers anObserver to receive KVO notifications for the specified key-path relative to the receiver.
Parameters
- anObserver
-
The object to register for KVO notifications. The observer must implement the key-value observing method
observeValueForKeyPath:ofObject:change:context:
. - keyPath
-
The key path, relative to the receiver, of the property to observe. This value must not be
nil
. - options
-
A combination of the
NSKeyValueObservingOptions
values that specifies what is included in observation notifications. For possible values, see “NSKeyValueObservingOptions.” - context
-
Arbitrary data that is passed to anObserver in observeValueForKeyPath:ofObject:change:context:.
Discussion
KVO等具体实现步骤以及注意事项的更多相关文章
- 【Azure Redis 缓存 Azure Cache For Redis】Azure Redis由低级别(C)升级到高级别(P)的步骤和注意事项, 及对用户现有应用的潜在影响,是否需要停机时间窗口,以及这个时间窗口需要多少的预估问题
问题描述 由于Azure Redis的性能在不同级别表现不同,当需要升级/缩放Redis的时候,从使用者的角度,需要知道有那些步骤? 注意事项? 潜在影响?停机事件窗口? 升级预估时间? 解决方案 从 ...
- spring4+hibernate4+struts2项目整合的步骤及注意事项
首先,在整合框架之前,我们需要知道Spring框架在普通Java project和Web project中是略有不同的. 这个不同地方就在于创建IOC容器实例的方式不同,在普通java工程中,可以在m ...
- 自定义Camera综述(一般步骤、注意事项、遇到的难题<【内存溢出问题】>、像素参考)
一般步骤: 1. 检查和访问Camera:创建代码来检查Camera和所申请访问的存在性: 2. 创建一个预览类:继承SurfaceView来创建一个Camera的预览类,并实现SurfaceHold ...
- cocos2d-x笔记2: 编译到安卓的步骤与注意事项
博客地址: www.cnblogs.com/wolfred7464/ 不得不说,真心复杂,本篇博客总结的基本是最简最直接的步骤了,不用Cygwin和Ant的,当然用也可以... 以下用 %PROJEC ...
- redis cluster 集群搭建步骤和注意事项
1.安装Ubuntu ,修改root的密码. sudo passwd (apt-get update 更新系统) 2.安装 Gcc 和G++ sudo apt-get install build- ...
- 简单使用Vuex步骤及注意事项
使用Vuex的步骤: (1)安装: 1.使用npm安装: npm install vuex --save 2.使用script标签引入 <script src="/path/to/vu ...
- 整合struts2+hibernate详细配置步骤及注意事项
刚刚学完这两个框架,就迫不及待的做了一个例子,在整合两个框架的时候,也碰到了一些小问题,下面介绍一下配置的步骤: 1.创建一个自定义的struts2和hibernate的类库 因为之前写例子都是直接将 ...
- 给11gR2 Dataguard打psu补丁的步骤及注意事项
参考文档278641.1 0.备份备主备库的spfile备份主库的数据 1.在主库上暂停向备库传日志alter system set log_archive_dest_state_X=defer sc ...
- MySQL主备停机步骤与注意事项
双十一马上到了,一堆的事情,今天登录mysql数据库服务器的时候突然发现服务器时间戳不对,比北京时间快了几分钟,我的天...随后检查了其他的几台数据库服务器发现同样都存在不同的偏差,最小的比北京时间快 ...
随机推荐
- Webstorm下安装ESLint检测JS代码
今天配置下Webstorm下面的Eslint, 先看下本地安装的Node,NPM版本,2017-11-23日这个节点最新版本. >node -v v8.9.1 >npm -v 使用Webs ...
- vue 组件中数组的更新
今天写项目时遇到的问题,瞬间就卡在那了 来还原一下: parent.vue: <template> <div> <button @click="change&q ...
- Pyqt5学习系列
最近在学习Pyqt5做界面,找到了一个非常棒的博主的学习系列 在此记录下来: http://blog.csdn.net/zhulove86/article/category/6381941
- 实战Excel Add-in的三种玩法
作者:陈希章 发表于 2017年11月26日 前言 这个系列文章应该有一阵子没有更新了,原因是一如既往的多,但是根本所在是我对于某些章节其实还没有完全想好怎么写,尤其是对于Office Add-in这 ...
- 用JS实现Ajax请求
AJAX核心(XMLHttpRequest) 其实AJAX就是在Javascript中多添加了一个对象:XMLHttpRequest对象.所有的异步交互都是使用XMLHttpServlet对象完成的. ...
- C++PRIMER 阅读笔记 第三章
本章主要介绍 string vector 和 bitset, 不能贪多,现在本文主要介绍 string 与 vector 头文件中最好不要使用namespace std, 因为头文件会直接被预处理器放 ...
- UVA 1508 - Equipment dp状态压缩
题意: 已知n个5元组,从中选出k组,使得这些组中5个位置,每个位置上最大数之和最大. 分析:当k>5时,就是n个5元组最大的数之和,当k<5时,就当做5元组,状态压缩,用00000表示 ...
- VSCode 同步设置及扩展插件 实现设备上设置统一
准备工作:电脑上需安装VSCode,拥有一个github账户.实现同步的功能主要依赖于VSCode插件 "Settings Sync" Setting Sync 可同步包含的所有扩 ...
- 51Nod--1018排序
1018 排序 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出N个整数,对着N个整数进行排序 Input 第1行:整数的数量N(1 <= N ...
- javascript算法题判断输入年份是否是闰年
用户输入一个年份,判断这个年是否是闰年.判断闰年条件:① 非整百年数除以4,无余为闰,有余不闰:② 整百年数除以400,无余为闰,有余不闰.比如:2000年,整百数年,就要用②公式,除以400,无余数 ...