对NSObject写一个分类:
#import <Foundation/Foundation.h>
@interface NSObject (FMObserverHelper)
- (void)fm_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
@end
// 对象被释放之前, 会调用dealloc方法, 其持有的实例变量也会被释放.
// 在监听注册时, 为self和Observer关联个临时对象, 当两者在释放实例变量时, 借助这个时机, 在临时对象的dealloc方法中, 移除Observer
// self在被释放之前, 会先释放其持有的关联属性, self并未完全释放, 可在临时对象中target却成了nil.
// weak: 持有者不会对目标进行retain, 当目标销毁时, 持有者的实例变量会被置空
// unsafe_unretained: 持有者不会对目标进行retain, 当目标释放后, 持有者的实例变量还会依然指向之前的内存空间(野指针)
// 如果Observer提前释放,而添加关联属性, 两者还不能同时持有临时对象, 否则临时对象也不会及时的释放,既然一个不行, 那就各自关联一个.
// 两个关联属性释放的同时, 进行了两次观察移除的操作. 为避免这个问题, 需要判断weak引用的实例变量factor是否为空即可
#import "NSObject+FMObserverHelper.h"
#import <objc/runtime.h>
@interface FMObserverHelper : NSObject
@property (nonatomic, unsafe_unretained) id target;
@property (nonatomic, unsafe_unretained) id observer;
@property (nonatomic, strong) NSString * keyPath;
@property (nonatomic, weak) FMObserverHelper * factor;
@end
@implementation FMObserverHelper
- (void)dealloc {
if ( _factor ) {
[_target removeObserver:_observer forKeyPath:_keyPath];
}
}
@end
@implementation NSObject (FMObserverHelper)
- (void)fm_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath {
[self addObserver:observer forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:nil];
FMObserverHelper * helper = [FMObserverHelper new];
FMObserverHelper * sub = [FMObserverHelper new];
sub.target = helper.target = self;
sub.observer = helper.observer = observer;
sub.keyPath = helper.keyPath = keyPath;
helper.factor = sub;
sub.factor = helper;
const char * helpeKey = [NSString stringWithFormat:@"%zd", [observer hash]].UTF8String;
objc_setAssociatedObject(self, helpeKey, helper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(observer, helpeKey, sub, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
iOS 自动移除KVO观察者的更多相关文章
-
IOS学习之初识KVO
什么是KVO? KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制. 该如何使用? 1.注册,指定被 ...
-
CVS 文件自动移 tag 的 Python 脚本
CVS 文件自动移 tag 的 Python 脚本 背景 工作中使用的版本管理工具是 CVS,在两次发布中,如果修改的文件比较少,会选择用移 Tag 的方式来生成一个新 Tag 发布.文件比较少的情况 ...
-
iOS NSNotificationCenter 移除通知带来的crash
Where to remove observer for NSNotification? 在dealloc方法中移除通知观察者带来crash NSNotificationCenter中的通知消息已经发 ...
-
ios自动打包-fastlane 安装、使用、更新和卸载
ios自动打包使用fastlane 1.首先安装xcode 首先检查是否已经安装 Xcode 命令行工具,fastlane 使用 xcodebuild 命令进行打包,运行 xcode-select - ...
-
40、IOS自动打包-Python脚本
第一种:基于编译的打包 编译工程--找到.app文件--新建Payload文件夹--拷贝.app到Payload文件夹--压缩成zip--更改后缀名为ipa--完成! 第二种(有问题,暂时不需要看) ...
-
ios - kvo观察者示例
首先创建Person分类 #import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatom ...
-
【原】iOS中KVC和KVO的区别
在iOS开发中经常会看到KVC和KVO这两个概念,比较可能混淆,特地区分一下 KVC(Key Value Coding) 1> 概述 KVC:Key Value Coding,键值编码,是一种间 ...
-
iOS 中KVC、KVO、NSNotification、delegate 总结及区别-b
1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...
-
【iOS】KVC 与 KVO
一.KVC与KVO *"KVC":key value Coding(键值编码) *目的:间接的改动或获取对象的属性,减少程序(类与类)之间的耦合度. *"KVO" ...
随机推荐
-
Optimizely:在线网站A/B测试平台
Optimizely:在线网站A/B测试平台是一家提供 A/B 测试服务的公司.A/B 测试能够对比不同版本的设计,选取更吸引用户眼球的那一款,从而带来更为优化的个人体验.让网站所有者易于对不同版本的 ...
-
从最小角回归(LARS)中学到的一个小知识(很短)
[转载请注明出处]http://www.cnblogs.com/mashiqi (居然有朋友说内容不接地气,那么我就再加一段嘛,请喜欢读笑话的同学直接看第二段)假设这里有一组向量$\left\{ x_ ...
-
iOS网络编程笔记——社交网络编程
社交网络编程主要使用iOS提供的social框架,目前social框架主要分为两个类: (1)SLComposeViewController提供撰写社交信息(如微博信息)的视图控制器,由iOS系统提供 ...
-
爬取IP
import urllib.request import re def url_open(url): req = urllib.request.Request(url,headers={'User-A ...
-
深耕品质,腾讯WeTest《2018中国移动游戏质量白皮书》正式发布
本文由云+社区发表 作者:腾讯WeTest 原文链接:https://wetest.qq.com/lab/view/437.html 对于游戏行业的不少人来说,2018年是一个多事之秋. 放眼大局,游 ...
-
[LeetCode] Bricks Falling When Hit 碰撞时砖头掉落
We have a grid of 1s and 0s; the 1s in a cell represent bricks. A brick will not drop if and only i ...
-
org.hibernate.AssertionFailure: null id in xxx entry (don&#39;t flush the Session after an exception occurs)
网上找了很久,发现造成原因有很多种,后来终于发现了端倪:看提示是发生了异常,查看业务代码,发现有这个逻辑:先插入记录,如果有唯一键约束异常(并发造成),catch时查询已存在的记录,查询的时候就报了此 ...
-
antd 知识点
表格实现:不管多少列,为列指定一个宽度,让表格在容器里可左右拖动 例子文件地址:https://github.com/cag2050/antd_mobx_demo/blob/master/src/co ...
-
[转]python的requests发送/上传多个文件
1.需要的环境 Python2.X Requests 库 2.单字段发送单个文件 在requests中发送文件的接口只有一种,那就是使用requests.post的files参数, 请求形式如下: ...
-
Linux输入输出重定向和文件查找值grep命令
Linux输入输出重定向和文件查找值grep命令 一.文件描述符Linux 的shell命令,可以通过文件描述符来引用一些文件,通常使用到的文件描述符为0,1,2.Linux系统实际上有12个文件描述 ...