iOS 自动移除KVO观察者
对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" ...
随机推荐
- JS高级 - 面向对象3(面向过程改写面向对象)
改写: 1.前提:所有东西都在 onload 里 2.改写:不能有函数嵌套,可以有全局变量 onload --> 构造函数 全局变量 --> 属性 函数 --> 方法 4.改错: t ...
- hdu 1258 从n个数中找和为t的组合 (DFS)
题意:首先给你一个t,然后是n,后面输入n个数,然后让你求的是n个数中和为t的序列总共有多少种,把他们按从左到右的顺序输出来. Sample Input4 6 4 3 2 2 1 15 3 2 1 1 ...
- 转 关于Https协议中的ssl加密解密流程
关于Https协议中的ssl加密解密流程 2016年09月28日 09:51:15 阅读数:14809 转载自:http://www.cnblogs.com/P_Chou/archive/2010/1 ...
- Codeforces 757D - Felicity's Big Secret Revealed
757D - Felicity's Big Secret Revealed 题目大意:给你一串有n(n<=75)个0或1组成的串,让你划最多n+1条分割线,第一条分割线的前面和最后一条分割线的后 ...
- js中setInterval和setTimeout区别和用法
setTimeout setTimeout() //- 在指定时间后执行代码clearTimeout() //- 取消 setTimeout(),clearTimeout()方法的参数必须是由setT ...
- 【Java】 剑指offer(56-1) 数组中只出现一次的两个数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程 ...
- hdu1873 看病要排队【优先队列】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1873 看病要排队 Time Limit: 3000/1000 MS (Java/Others) ...
- C++雾中风景番外篇:理解C++的复杂声明与声明解析
在学习C系列语言的过程之中,理解C/C++的复杂声明一直是初学者很困扰的问题.笔者初学之时也深受困扰,对很多规则死记硬背.后续在阅读<C专家编程>之后,尝试在编译器的角度来理解C/C++的 ...
- Flutter常用组件(Widget)解析-Scaffold
实现一个应用基本的布局结构. 举个栗子: import 'package:flutter/material.dart'; void main() => runApp(MyApp()); clas ...
- 零拷贝-zero copy
Efficient data transfer through zero copy Zero Copy I: User-Mode Perspective 0. 前言 在阅读RocketMQ的官方文档时 ...