weak的实现原理

news/2024/7/20 12:37:58 标签: objective-c, weak, 原理, 面试, 内存管理
         iOS 在运行时维护着一个全局的弱引用表,该表是一个 hash 表,hash表的 key 是 对象本身,value 是指向该对象的所有 weak 指针的地址数组。   
/**
   全局的弱引用表,本质是一个hash结构,对象本身作为key, 
   存储weak修饰的指针地址的weak_entry_t作为value
 */
struct weak_table_t {
    // 保存了所有指向特地对象的 weak指针集合
    weak_entry_t *weak_entries;
    // hash数组中元素个数
    size_t num_entries;
    // hash数组的长度,而不是元素个数。比如,数组长度可能是64,而元素个数仅存了2个
    uintptr_t mask;
    // hash冲突最大次数, hash数组采用开放定址法解决hash冲突
    uintptr_t max_hash_displacement;
};
        以下述代码为例:
NSObject * obj =  [[NSObject alloc] init];

__weak NSObject *p1 = obj;
__weak NSObject *p2 = obj;

NSObject ** referrer1 = &p1;
NSObject ** referrer2 = &p2;

[obj release];

         hash表的key为obj,hash表的值weak_entries的referers属性被赋值为[referrer1, referrer2];

        当weak修饰的对象obj被销毁时,iOS在运行时会从哈希表中查找到所有指向此对象的 weak 指针,并将其全部置为空 nil,即通过执行*referrer1 = NULL和*referrer2 = NULL,实现将p1和p2置为NULL。
 
weak_clear_no_lock(weak_table_t *weak_table, id referent_id) {
    // 在weak_table中对应的weak_entry_t
    objc_object *referent = (objc_object *)referent_id;
    weak_entry_t *entry = weak_entry_for_referent(weak_table, referent); 
    weak_referrer_t referrers = entry->referrers;
    int count = TABLE_SIZE(entry);

    for (size_t i = 0; i < count; ++i) {
        objc_object **referrer = referrers[i]; 
        if (referrer) {
            // 如果weak指针确实弱引用了对象 referent,则将weak指针设置为nil
            if (*referrer == referent) { 
                *referrer = nil;
            }
        }
    }
}

        iOS在ARC下通过引入weak标识, 大大减少了以前retain或assign标识的对象在被销毁后可能出现野指针的情况,进而有效提升了代码健壮性。


http://www.niftyadmin.cn/n/5399831.html

相关文章

Oracle 提示(hint)方法:use_nl

select /* index(e) index(d) use_nl(e d) */ * from emp e inner join dept d on e.deptnod.deptno where e.ename :b1 or d.dname :b2; USE_NL 是一个提示&#xff08;hint&#xff09;&#xff0c;用于指示查询优化器使用"NESTED LOOPS"连接方式。该提示告诉…

Python WikiGPT代码,GPT代码实战,逐行讲解GPT代码,教你完整写完GPT代码,GPT代码模板,一文教你学会写GPT代码

1.GPT基本介绍 在GPT1诞生之前&#xff0c;NLP领域已存在多种任务&#xff0c;比如文本分类、语义相似度&#xff0c;以及问答等&#xff0c;这些任务的共同点在于它们都是有监督学习&#xff0c;且各自维护不同的量级较小的训练语料。OpenAI为了进一步提升这些任务的预测效果&…

【OpenGL的着色器03】内置变量(gl_Position等)

目录 一、说明 二、着色器的变量 2.1 着色器变量 2.2 着色器内置变量 三、最常见内置变量使用范例 3.1 常见着色器变量 3.2 示例1&#xff1a; gl_PointSize 3.3 示例2&#xff1a;gl_Position 3.4 gl_FragColor 3.5 渲染点片元坐标gl_PointCoord 3.6 gl_PointCoo…

基于R语言piecewiseSEM结构方程模型在生态环境领域技术应用

结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;可分析系统内变量间的相互关系&#xff0c;并通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和广泛的适用性&#xff0c;是近年来生态、进化、环境、地学、…

一文了解游戏从立项到发行的流程

背景 玩家从app商店下载一个游戏,看到了只是一个游戏客户端。那么,游戏从立项到用户下载,会经过哪些职能部门呢? 游戏项目经过的部门可以因公司和项目的规模而有所不同,但通常会涉及以下部门: 游戏相关部门 项目经理/制作人:研发团队核心角色,负责协调和管理游戏项目…

Unity3D 法线贴图的原理详解

前言 Unity3D它提供了丰富的功能和工具&#xff0c;帮助开发者轻松创建出高质量的游戏作品。其中&#xff0c;法线贴图&#xff08;Normal Mapping&#xff09;是一种常用的技术&#xff0c;用于在游戏中模拟出高精度的表面细节&#xff0c;提升游戏画面的真实感和细节感。本文…

GEE入门篇|图像处理(二):在Earth Engine中进行波段计算

目录 波段计算 1.NDVI的计算 2.NDVI 归一化差值的单次运算计算 3.使用 NDWI 的归一化差值 波段计算 许多指数可以使用 Earth Engine 中的波段运算来计算。 波段运算是对图像中两个或多个波段进行加、减、乘或除的过程。 在这里&#xff0c;我们将首先手动执行此操作&#x…

Java——建造者模式(Builder)

建造者模式&#xff08;Builder&#xff09; 1、建造者模式的定义 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 Builder模式是一步一步创建一个复杂对象的创建型模式&#xff0c;它允许使用者在不知道内部建造细节的情况下&…