__weak简析

作者: 一个人在路上走下去 | 来源:发表于2015-12-08 14:23 被阅读606次

当一个 __weak 类型的指针指向的对象被释放时,该指针会自动被置成nil,因此__weak关键字修饰的指针又被称为智能指针。那么这个功能是如何实现的呢?

id __weak obj1 = obj; 

会转化为

id obj1;  
objc_initWeak(&obj1, obj);  
objc_destoryWeak(&obj1);  

即编译器会通过objc_initWeak函数初始化__weak修饰的变量,当变量的作用域结束后会通过objc_destoryWeak函数释放该变量。objc_initWeak函数实际干的活是:

objc1 = 0;  
objc_storeWeak(&obj1, obj);  

这里是先将指针objc1置成0,再调用objc_storeWeak函数使得obj1指向obj对象。
接下来的objc_destoryWeak函数的实际操作如下:

objc_storeWeak(&obj1, 0); 

也就是说,让obj1指针指向的内容变成空。

__weak实现原理

实际上,objc_storeWeak函数会把第二个参数的对象的地址作为key,并将第一个参数(__weak关键字修饰的指针的地址)作为值,注册到weak表中。如果第二个参数为0(说明对应的对象被释放了),则将weak表中将整个key-value键值对删除,这就是__weak关键字的核心思想!

weak表和引用计数表类似,都是通过hash表实现的。如果使用weak表,将被释放的对象地址作为key去检索,就能很高效的获取对应的指向该对象的类型为__weak的指针变量的地址。同时很容易理解,一个对象可能有多个__weak指针指向,因此一个对象地址key可能对应多个值。

在调用对象的release方法时,会在其中一步调用objc_clear_deallocating函数,该函数会执行以下操作:以当前对象的地址作为key,从weak表中获取对应的值----指向该对象的__weak类型的指针变量;将取到的所有指针变量的值赋值为nil;从weak表中删除该key对应的整条记录。

如果大量使用附有__weak修饰符的变量会消耗响应的CPU资源,因此,应该尽量少使用__weak修饰符。

相关文章

  • __weak简析

    当一个 __weak 类型的指针指向的对象被释放时,该指针会自动被置成nil,因此__weak关键字修饰的指针又被...

  • __weak简析

    弱引用在oc中被经常用到的,用__weak修饰的对象不会引用计数+1,不会被强引用。那么__weak是怎么做到的呢...

  • Swift-11.析构方法和内存管理

    本章包含内容: 析构过程原理 析构器实践 Swift语言的内存管理分析 weak引用(弱引用) unowned引用...

  • mybatis-spring解析

    1、概述 原生Mybatis源码简析(上)原生Mybatis源码简析(下)在介绍原生Mybatis源码简析文章中,...

  • 简析 Swift 的模块系统

    简析 Swift 的模块系统 简析 Swift 的模块系统

  • 简析Swift和C的交互

    简析Swift和C的交互 简析Swift和C的交互

  • 2018-11-20 weak实现原理 - 简书

    weak实现原理 - 简书

  • shiro原理简析+基于springboot基础实践

    1、shiro原理简析 原理简析: 1、subject支持不通调用获取用户信息 2、SecurityManager...

  • Spring Boot启动流程简析

    Spring Boot启动流程简析 木叶之荣,2017年12月 Spring Boot启动流程简析(一) Spri...

  • 简叙weak

    weak故名思义就是弱~与其相对应的不免想到strong。所以作为小受的weak它本身是一种非拥有的关系。 那什么...

网友评论

    本文标题:__weak简析

    本文链接:https://www.haomeiwen.com/subject/gbuehttx.html