我们可以自己创建一个 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. [Math] Unconstrained & Constrained Optimization

    粘贴两个典型的例子,只是基础内容,帮助理解. (1) Solution: (2) Solution:

  2. react列表数据显示

    react的列表数据一般是用map循环显示的. 使用map注意:map的回调函数为箭头函数时,后面如果加大括号(箭头函数常规编写),必须要有return才可以,如果箭头函数后面没有大括号(箭头函数简写 ...

  3. LostRoutes项目日志——编辑project.json

    第一个Scene编译后运行会报错: Uncaught TypeError: Cannot read property 'style' of null 这是因为没有在project.json中包含已经编 ...

  4. Ubuntu下SSH无密码验证配置

    前言 SSH为Secure Shell 的缩写,是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议.越来越多的小伙伴们使用远程登录,而ssh安全性无疑是很高的,那么我们现在来看看如何实现ss ...

  5. openresty的安装和使用

    1,简介 OpenResty(又称:ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台,是一个强大的 Web 应用服务器,在性能方面,OpenResty可以 快速构造出足以 ...

  6. 【连载6】二手电商APP的导购功能与关系链机制分析

    导读:得益于十余年来各种一手电商平台对市场与用户的教育以及共享.分享经济浪潮的兴起,互联网化的二手.闲置商品买卖.置换成为越来越普遍且简单可实现的生活方式. 第三章目录: 三.对比:主流二手电商竞品的 ...

  7. VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService......匹配的导出

    错误信息: 点击解决方案中的文件,就会提示这个错误.最近给vs2013安装了python的插件,安装了vs2017的python,可能是这两个导致了这个错误. 解决方案: 删除 C:\Users\ji ...

  8. 配置nginx实现windows/iis应用负载均衡

    nginx是俄罗斯人开发的一款跨平台的高性能HTTP和反向代理服务器,可以利用它实现web应用服务器的负载均衡. 反向代理是指将用户请求通过代理服务器转发给后端内部网络的应用服务器,典型的应用比如配置 ...

  9. [破解] nasca drm file -ver1.00

    在使用nasca系统中的下载相应的文件时,默认下载会被Nasca加密,可以通过下面的方式进行免除加密. 首先我们需要了解没有加密系统的默认下载过程: 当下载文件33333333333.pdf时,由于文 ...

  10. Cannot change version of project facet Dynamic Web Module to 3.0 异常问题处理

    如何解决Tomcat服务器在初始化应用的时候的以下异常问题 1,Cannot change version of project facet Dynamic Web Module to 3.0 2,O ...