一、weak 属性特点

  • weak 表明该属性定义了一种“非拥有关系” (nonowning relationship);
  • 为 weak 属性设置新值时,设置方法既不保留新值,也不释放旧值;
  • 同 assign 类似,然而在属性所指的对象释放时候,属性值也会清空(nil out)。

二、runtime 如何实现 weak 属性

① 实现步骤
  • 初始化时:runtime 会调用 objc_initWeak 函数,初始化一个新的 weak 指针指向对象的地址。
  • 添加引用时:objc_initWeak 函数会调用 objc_storeWeak(&weakPo, Model) 函数。
  • 释放时:调用 clearDeallocating 函数,clearDeallocating 函数首先根据对象地址获取所有 weak 指针地址的数组,然后遍历这个数组把其中的数据设为 nil,最后把这个 entry 从 weak 表中删除,最后清理对象的记录。
② objc_storeWeak(&weakPo, Model) 作用
  • objc_storeWeak(&weakPo, Model) 的作用是更新指针指向(指针可能原来指向着其他对象,这时候需要将该 weak 指针与旧对象解除绑定,会调用到 weak_unregister_no_lock),如果指针指向的新对象非空,则创建对应的弱引用表,将 weak 指针与新对象进行绑定(即把赋值对象(Model)的内存地址作为键值key,将weak修饰的属性变量(weakPo)的内存地址(& weakPo)作为value),会调用到weak_register_no_lock,注册到 weak 表中。在这个过程中,为了防止多线程中竞争冲突,会有一些锁的操作。
  • 如果Model 为0(nil),那么把变量 weakPo 的内存地址 &weakPo 从 weak 表中删除,可以把 objc_storeWeak(&weakPo, Model) 理解为:objc_storeWeak(value, key),并且当key变nil,将value置nil。
  • 在 Model 非 nil 时,weakPo 和 Model 指向同一个内存地址,在 Model 变 nil 时,weakPo 变 nil。此时向 weakPo 发送消息不会崩溃:在 Objective-C 中向 nil 发送消息是安全的。

三、runtime 是如何实现 weak 变量的自动置 nil ?

  • runtime 对注册的类,会进行内存布局,从一个粗粒度的概念上来讲,这时候 weak 对象会放入一个 hash 表中,这是一个全局表,表中是用 weak 指向的对象内存地址作为 key,用所有指向该对象的 weak 指针表作为 value。
  • 当此对象的引用计数为 0 的时候会 dealloc,假如该对象内存地址是 address,那么就会以 address 为 key,在这个weak 表中搜索,找到所有以 address 为键的 weak 对象,从而设置为 nil。
  • 简而言之,对象释放的时候 - dealloc: 步骤如下:
    • C++函数释放: object_ cxxDestruct;
    • 移除关联属性:_ object_ remove_ assocations;
    • 将弱引用自动设置nil : weak_ clear_ no_ lock(&table.weak_ table, (id)this);
    • 引用计数处理: table.refcnts.erase(this);
    • 销毁对象: free(obj);

四、weak 底层调用流程

iOS经典面试题之“runtime是如何实现weak变量的自动置nil”相关推荐

  1. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  2. 李洪强iOS经典面试题153- 补充

    李洪强iOS经典面试题153- 补充   补充 有空就来解决几个问题,已经懒癌晚期没救了... UML 统一建模语言(UML,UnifiedModelingLanguage)是面向对象软件的标准化建模 ...

  3. 李洪强iOS经典面试题36-简单介绍 ARC 以及 ARC 实现的原理

    李洪强iOS经典面试题36-简单介绍 ARC 以及 ARC 实现的原理 问题 简单介绍 ARC 以及 ARC 实现的原理. 考查点 ARC 是苹果在 WWDC 2011 提出来的技术,因此很多新入行的 ...

  4. 李洪强iOS经典面试题37-解释垃圾回收的原理

    李洪强iOS经典面试题37-解释垃圾回收的原理 问题 我们知道,Android 手机通常使用 Java 来开发,而 Java 是使用垃圾回收这种内存管理方式. 那么,ARC 和垃圾回收对比,有什么优点 ...

  5. 李洪强iOS经典面试题144-数据存储

    李洪强iOS经典面试题144-数据存储   数据存储 sqlite中插入特殊字符的方法和接收到处理方法. 除'其他的都是在特殊字符前面加"/",而 ' -> '' .方法:k ...

  6. iOS经典面试题总结--内存管理

    内存管理 1.什么是ARC? ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release.在对象被创建时retain count+1 ...

  7. iOS经典面试题之使用runtime associate方法关联的对象释放及dealloc底层原理

    一.题目分析 使用 runtime associate 方法关联的对象,需要在主对象 dealloc 的时候释放吗? 无论在 MRC 下还是 ARC 下均不需要,被关联的对象在生命周期内要比对象本身释 ...

  8. iOS经典面试题大全

    1.INTERVIEW 共勉 作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:638302184,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题.面试经验,讨 ...

  9. 整理一篇iOS经典面试题大全

    ###1.INTERVIEW 共勉 ###2.iOS developers 方向 ###3.INTERVIEW QUESTION 1.深copy和浅copy 浅拷贝: 1.对内存地址的复制,让目标对象 ...

最新文章

  1. 软件测试工程师的角度看论证学问
  2. python综合案例分享_Python面向对象 三大特性 综合案例+1(视频里的作业)
  3. 面试官:前端跨页面通信,你知道哪些方法?
  4. pom.xml文件指定jdk版本号/跳过测试
  5. Spring Boot——[Disconnected from the target VM, address: IP:端口, transport: #39socket#39]解决方案
  6. java swing 控件拖动_java swing中实现拖拽功能示例
  7. java httpcomponents_java – 如何使用Apache httpcomponents从NHttpRequ...
  8. KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结
  9. java switch 不加 break 继续执行 下一个case(不用匹配条件) 这个设计是为什么
  10. java预览表格预览文档_java 如何创建一个表格.docx
  11. Eclipse SQL Explorer
  12. java 怎么使用 设计模式对业务进行解耦(一)
  13. Android 10.0 SystemUI修改状态栏电池图标样式为横屏显示
  14. 权限控制 JSR-250注解、@Secured注解、支持表达式的注解
  15. ae字体预设下载_20组经典的文字动画AE源文件,含20个AE预设
  16. 储留香:从丞相说到文件系统
  17. 波特率、比特、字、千字节、兆、G之间转换
  18. 初始内省Introspection
  19. 饥荒海难机器人怎么用_饥荒海难机器人作用详解 饥荒海难机器人有什么用
  20. java地铁最短距离_地铁线路最短路径问题

热门文章

  1. Robot Framework--环境搭建
  2. Docker 容器CPU设置
  3. 【2017级面向对象程序设计】作业一
  4. 我们越来越浮躁的心靠什么去滋润
  5. respberry pi3 上手随记
  6. android 制作的精美闹钟
  7. starting mysql. success!_启动mysql报错解决问题过程
  8. html抽奖源码_开源FPGA开发板OpenICE 介绍及抽奖
  9. vue3与vue2的详细区别
  10. Java黑皮书课后题第7章:7.26(完全相同的数组)如果两个数组list1和list2的对应元素都相等,认为完全相同。编写一个测试程序,提示用户输入两个整数列表,然后显示这两个列表是否完全相同