对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观察者的更多相关文章

  1. IOS学习之初识KVO

    什么是KVO? KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制. 该如何使用? 1.注册,指定被 ...

  2. CVS 文件自动移 tag 的 Python 脚本

    CVS 文件自动移 tag 的 Python 脚本 背景 工作中使用的版本管理工具是 CVS,在两次发布中,如果修改的文件比较少,会选择用移 Tag 的方式来生成一个新 Tag 发布.文件比较少的情况 ...

  3. iOS NSNotificationCenter 移除通知带来的crash

    Where to remove observer for NSNotification? 在dealloc方法中移除通知观察者带来crash NSNotificationCenter中的通知消息已经发 ...

  4. ios自动打包-fastlane 安装、使用、更新和卸载

    ios自动打包使用fastlane 1.首先安装xcode 首先检查是否已经安装 Xcode 命令行工具,fastlane 使用 xcodebuild 命令进行打包,运行 xcode-select - ...

  5. 40、IOS自动打包-Python脚本

    第一种:基于编译的打包 编译工程--找到.app文件--新建Payload文件夹--拷贝.app到Payload文件夹--压缩成zip--更改后缀名为ipa--完成! 第二种(有问题,暂时不需要看) ...

  6. ios - kvo观察者示例

    首先创建Person分类 #import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatom ...

  7. 【原】iOS中KVC和KVO的区别

    在iOS开发中经常会看到KVC和KVO这两个概念,比较可能混淆,特地区分一下 KVC(Key Value Coding) 1> 概述 KVC:Key Value Coding,键值编码,是一种间 ...

  8. iOS 中KVC、KVO、NSNotification、delegate 总结及区别-b

    1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...

  9. 【iOS】KVC 与 KVO

    一.KVC与KVO *"KVC":key value Coding(键值编码) *目的:间接的改动或获取对象的属性,减少程序(类与类)之间的耦合度. *"KVO" ...

随机推荐

  1. poj 2406 求字符串中重复子串的个数

    Sample Input abcdaaaaababab.Sample Output 1 //1个abcd4 //4个a3 //3个ab #include<stdio.h> #include ...

  2. win10定时执行php脚本

    转自http://www.cnblogs.com/wenhainan/p/6962089.html 第一步:确认windows上是否配置好了php环境变量,我用xampp安装的lamp环境,默认已经配 ...

  3. BZOJ2618 [Cqoi2006]凸多边形 凸包 计算几何

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2618 题意概括 给出多个凸包,求面积交. 题解 首先我们考虑两个凸包相交的情况. 例题:HDU16 ...

  4. T9 HDU1298

    就是字典树加dfs 把所有操作封在结构体里面 #include <cstdio> #include <cstring> #include <algorithm> # ...

  5. 018 spark on yarn (Job history)的配置,主要是yarn处跳转到历史聚合页面

    一:目标 1.目标 在yarn的8080页面可以跳转到spark的日志18080页面. 因为在运行spark之后,看对应的job的日志,这样直接连接,更合理直接. 2.总结 在后面可以看到,其实不需要 ...

  6. window.location方法获取URL

    window.location方法获取URL 统一资源定位符 (Uniform Resource Locator, URL) 完整的URL由这几个部分构成: scheme://host:port/pa ...

  7. Python Django 学习 (一) 【Django 框架初探】

    1. 简介: Python下有许多款不同的 Web 框架.Django是重量级选手中最有代表性的一位.2008年9月发布第一个版本,目前的Django版本应该是2.1. 2. 本文的环境 OS : W ...

  8. MacBook快速入门

    入职新美大,全面进入Mac工作环境,果断"撸起袖子加油干","浪起来,逼格提起来".顺道提一嘴,这边的兄弟们的干劲是真心足,作为一名老兵痞,必须要虚心向身边NX ...

  9. SQLite中的运算符表达式

    SQLite中的运算符表达式 在SQLite中,运算符包括了一元运算符,二元运算符(二进制运算符)和三元元素符.图3.12中给出了这些运算符需要的参数以及优先级.其中,一元运算符的优先级最高,三元运算 ...

  10. 在webpack中使用postcss之插件cssnext

    学习了precss插件包在webpack中的用法后,下面介绍postcss的另一个重要插件cssnext,步骤没有precss用法详细,主要介绍css4的语法,cssnext目前支持了部分新特性,你可 ...