我们可以自己创建一个 A 类,然后在“宿主对象”和“值对象”建立 weak 关系的时候,偷偷地创建一个 A 类的实例 a,绑定在 “值对象” 上。
当“值对象”销毁后,这个 a 也会被销毁。而 A 类是轮子的内部类,其 dealloc 方法可以随意改造。
这样就可以把 宿主对象.某属性 = nil 这段代码写在 A 类的 dealloc 方法里。
由于 [a dealloc][值对象 dealloc] 是一起执行的,我们便做到在不改原有类的情况下捕获原有类的 dealloc 方法
总结来说在 Category 里我们要用关联对象的方法让“值类型”强引用 a。
 
/** 宿主类的分类实现 */
@implementation MUHostClass (Association)
const static char kValueObject = '0';
- (void)setValueObject:(MUValueClass *)valueObject {
  objc_setAssociatedObject(self, &kValueObject, valueObject, OBJC_ASSOCIATION_ASSIGN);
  /** * 1. 虽然这里没有循环引用,但是还是需要把弱引用丢给 block *
   因为 valueObj 持有 weakTask,weakTask 持有 block,block 持有 self *
   因此 self 至少要等到 valueObj 销毁后才能销毁。严重影响到 self 的生命周期 **/
   __weak typeof(self) wself = self;
  [valueObject setWeakReferenceTask:^{
    objc_setAssociatedObject(wself, &kValueObject, nil, OBJC_ASSOCIATION_ASSIGN); }
  ];
}
- (MUValueClass *)valueObject {
  return objc_getAssociatedObject(self, &kValueObject);
}
@end
/** 给所有的类添加扩展 */
@implementation NSObject (MUWeakTask)
static const char kWeakTask = '0';
- (void)setWeakReferenceTask:(TaskBlock)task {
  MUWeakTask *weakTask = [MUWeakTask taskWithTaskBlock:task];
  objc_setAssociatedObject(self, &kWeakTask, weakTask, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
/** 传说中的 A 类 */
@implementation MUWeakTask
- (instancetype)initWithTaskBlock:(TaskBlock)taskBlock{
  self = [super init];
  if (self) {
    _taskBlock = [taskBlock copy];
  }
  return self;
}
+ (instancetype)taskWithTaskBlock:(TaskBlock)taskBlock {
  return [[self alloc] initWithTaskBlock:taskBlock];
}
- (void)dealloc {
  if (self.taskBlock) {
    self.taskBlock();
  }
}
@end

runtime实现weak属性的更多相关文章

  1. runtime 如何实现 weak 属性

    出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙(子循),目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu 要实现 weak 属性,首先要搞清楚 ...

  2. weak属性需要在dealloc中置nil么?

    出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙(子循),目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu 不需要. 在ARC环境无论是强指针还是 ...

  3. OC 中的 weak 属性是怎么实现的?

    OC 中的 weak 属性是怎么实现的,为什么在对象释放后会自动变成 nil?本文对这个问题进行了一点探讨.环境 mac OS Sierra 10.12.4 objc709参考答案 搜索后发现runt ...

  4. Runtime(动态添加属性)

    下面通过一个实例展示一下Runtime(动态添加属性)的用法 下面对运行时添加属性用到的策略参数进行补充: 这样看来,前面的NSString* name用的策略是retain nonatomic就知道 ...

  5. runtime如何实现weak属性

    首先了解weak是一种非拥有关系,属性所值对象销毁时,属性值会清空(nil). Runtime对注册的类会进行布局,对于weak对象会放入hash表中,用weak指向的内存地址作为key,当对象引用计 ...

  6. ios专题 - objc runtime 动态增加属性

    objective-c中,有类别可以在不修改源码的基础上增加方法:近排在看别人的开源代码时,发现还可以动态增加属性.而且是在运行时,太牛B了. 使用运行时库,必须要先引入 objc/runtime.h ...

  7. objc runtime 动态增加属性

    objective-c中,有类别可以在不修改源码的基础上增加方法:近排在看别人的开源代码时,发现还可以动态增加属性.而且是在运行时,太牛B了. 使用运行时库,必须要先引入 objc/runtime.h ...

  8. delegate 为什么用 weak属性

    weak指针主要用于“父-子”关系,父亲拥有一个儿子的strong指针,因此是儿子的所有者:但是为了阻止所有权回环,儿子需要使用weak指针指向父亲:你的viewcontroller通过strong指 ...

  9. runtime怎么添加属性、方法等

    ivar表示成员变量 class_addIvar class_addMethod class_addProperty class_addProtocol class_replaceProperty

随机推荐

  1. 零基础 Vue 开发环境搭建 打开运行Vue项目

    [相关推荐]IntellIJ IDEA 配置 Vue 支持 打开Vue项目 所需文件 node.js环境(npm包管理器)(node-v8.11.3-x64.msi)(npmV5.6.0) cnpm ...

  2. 设计模式-行为型模式,python 中介者模式

    中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护.中介者模式属于行 ...

  3. JavaScript 之 function函数及参数arguments

    JavaScript用function关键字声明函数,可以用return返回值,也可以没有返回值. 建议:要么统一有返回值,要么统一都没有返回值,这样调试代码方便. 函数定义格式: function ...

  4. QT开发环境安装配置教程

    QT开发环境安装配置教程 分类: QT2012-11-29 23:31 35366人阅读 评论(12) 收藏 举报 Linux版的直接在ubutnu软件中心输入QT,安装响应的Designer,Cre ...

  5. [转]sudo找不到命令:修改sudo的PATH路径

    sudo有时候会出现找不到命令,而明明PATH路径下包含该命令,让人疑惑.其实出现这种情况的原因,主要是因为当 sudo以管理权限执行命令的时候,linux将PATH环境变量进行了重置,当然这主要是因 ...

  6. day_5.26python动态添加属性和方法

    python动态添加属性和方法 既然给类添加⽅法,是使⽤ 类名.⽅法名 = xxxx ,那么给对象添加⼀个⽅法 也是类似的 对象.⽅法名 = xxx '''2018-5-26 13:40:09pyth ...

  7. Convert PLY to VTK Using PCL 1.6.0 or PCL 1.8.0 使用PCL库将PLY格式转为VTK格式

    PLY格式是比较流行的保存点云Point Cloud的格式,可以用MeshLab等软件打开,而VTK是医学图像处理中比较常用的格式,可以使用VTK库和ITK库进行更加复杂的运算处理.我们可以使用Par ...

  8. rxjs 常用的静态操作符

    操作符文档 API create const { Observable } = require('rxjs'); // 创建 Observables var observable = Observab ...

  9. python操作文件

    OS模块 1.getcwd() 用来获取当前工作目录 >>> import os >>> os.getcwd() 'D:\\Postgraduate\\Python ...

  10. 使 用 Jquery 全选+下拉+单选+事件+挂事件

    先引用Jquery代码包 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...