iOS - 自定义引用计数(MRC)

自定义引用计数(Custom Reference Counting)是指类可以通过重写 retain/release 等方法来实现自己的引用计数管理机制。这通常用于特殊场景下的内存管理优化。

1. 判断是否使用自定义引用计数

inline bool 
objc_object::hasCustomRR() {
    // 检查类是否实现了自定义的引用计数方法
    return ISA()->hasCustomRR();
}

// 调用路径
id objc_object::retain() {
    if (fastpath(!ISA()->hasCustomRR())) {
        // 使用系统默认的引用计数机制
        return sidetable_retain();
    } else {
        // 使用类自定义的引用计数机制
        return ((id(*)(objc_object *, SEL))objc_msgSend)(this, @selector(retain));
    }
}

2. 自定义引用计数的实现示例

@interface CustomObject : NSObject

@property (nonatomic, assign) NSUInteger customRefCount;

@end

@implementation CustomObject

- (id)retain {
    @synchronized(self) {
        self.customRefCount++;
    }
    return self;
}

- (void)release {
    BOOL shouldDealloc = NO;
    @synchronized(self) {
        self.customRefCount--;
        if (self.customRefCount == 0) {
            shouldDealloc = YES;
        }
    }
    
    if (shouldDealloc) {
        [self dealloc];
    }
}

- (NSUInteger)retainCount {
    @synchronized(self) {
        return self.customRefCount;
    }
}

3. 使用场景

3.1 单例对象

@implementation MySingleton

+ (instancetype)sharedInstance {
    static MySingleton *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}

// 防止释放
- (id)retain {
    return self;
}

- (oneway void)release {
    // 不执行任何操作
}

- (id)autorelease {
    return self;
}

3.2 特殊内存管理

@implementation PooledObject

// 对象池中的对象
- (id)retain {
    // 不增加引用计数,而是返回到对象池
    [[ObjectPool sharedPool] markAsInUse:self];
    return self;
}

- (void)release {
    // 不真正释放,而是返回到对象池
    [[ObjectPool sharedPool] returnToPool:self];
}

4. 注意事项

4.1 线程安全

- (id)retain {
    @synchronized(self) {
        // 确保线程安全的引用计数操作
        _customRefCount++;
    }
    return self;
}

4.2 内存泄漏防护

- (void)release {
    BOOL shouldDealloc = NO;
    {
        @synchronized(self) {
            _customRefCount--;
            if (_customRefCount == 0) {
                shouldDealloc = YES;
            }
        }
    }
    
    // 在同步块外执行 dealloc
    if (shouldDealloc) {
        [self dealloc];
    }
}

5. 优缺点

优点:

  1. 可以实现特殊的内存管理策略
  2. 适合特定场景的优化
  3. 可以实现对象池等高级功能

缺点:

  1. 增加代码复杂度
  2. 可能引入bug
  3. 需要格外注意线程安全
  4. 可能影响系统的内存管理优化

6. 最佳实践

@implementation CustomRefCountObject

// 1. 清晰的文档
/**
 * 这个类使用自定义引用计数来实现对象池
 * 注意:不要直接创建实例,请使用 getFromPool 方法
 */

// 2. 完整的方法实现
- (id)retain {
    if (_customManaged) {
        return [self customRetain];
    }
    return [super retain];
}

// 3. 防御性编程
- (void)release {
    if (_customManaged) {
        [self customRelease];
        return;
    }
    [super release];
}

// 4. 调试支持
- (NSUInteger)retainCount {
    if (_customManaged) {
        return [self customRetainCount];
    }
    return [super retainCount];
}

自定义引用计数应该谨慎使用,只在确实需要的特殊场景下采用。大多数情况下,系统默认的引用计数机制就足够了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949526.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【每日学点鸿蒙知识】Hap 安装失败、ArkTS 与C++ 数组转换、渐变遮罩效果等

1、在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install failed due to older sdk version in the device”错误信息。 这是由于编译打包所使用的SDK版本与设备镜像版本不匹配。不匹配的场景包括: 场景一:设备上…

分布式搜索引擎之elasticsearch基本使用3

分布式搜索引擎之elasticsearch基本使用3 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络: docker network create es-net1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的镜像&…

在macOS上安装MySQL

macOS的MySQL有多种不同的形式: 1、本机包安装程序,它使用本机macOS安装程序(DMG)引导您完成MySQL的安装。有关详细信息,请参阅第2.4.2节,“使用本机包在macOS上安装MySQL”。您可以将包安装程序与macOS一…

Apache HTTPD 换行解析漏洞(CVE-2017-15715)

漏洞简介 pache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。 漏洞环境 vulhub/httpd/CVE-2…

jenkins入门4 --window执行execute shell

1、启动关闭jenkins 在Windows环境下,如果你需要关闭Jenkins服务,可以通过以下几种方式: 1、使用Windows服务管理器: 打开“运行”对话框(Win R),输入services.msc,然后回车。 在服…

conda安装及demo:SadTalker实现图片+音频生成高质量视频

1.安装conda 下载各个版本地址:https://repo.anaconda.com/archive/ win10版本: Anaconda3-2023.03-1-Windows-x86_64 linux版本: Anaconda3-2023.03-1-Linux-x86_64 Windows安装 环境变量 conda -V2.配置conda镜像源 安装pip conda…

医学图像分析工具01:FreeSurfer || Recon -all 全流程MRI皮质表面重建

FreeSurfer是什么 FreeSurfer 是一个功能强大的神经影像学分析软件包,广泛用于处理和可视化大脑的横断面和纵向研究数据。该软件由马萨诸塞州总医院的Martinos生物医学成像中心的计算神经影像实验室开发,旨在为神经科学研究人员提供一个高效、精确的数据…

vite打包报错“default“ is not exported by “node_modules/dayjs/dayjs.min.js“

vite打包最开始报的错是: 查找各种解决办法后,第一次尝试如下: npm i rollup/plugin-commonjs npm i vite-plugin-require-transform但继续报错: 最后解决办法为: 忽略掉node_modules 在vite.config.ts里修改代码 …

医院管理住院系统的研究与实现

第三章 系统的需求分析和可行性研究 3.1 功能需求 经过对本系统的研究分析,本系统主要是为了方便让医院更快捷的管理。所面向的对象主要有病人、医生和医院的管理人员。病人运用该系统后,可以根据该系统查看自己所需要的信息,包括治疗自己…

安徽省地图arcgis数据美化后mxd文件shp格式下载后内容测评

标题中的“安徽省地图arcgis数据美化后mxd文件shp格式”揭示了这个压缩包的内容是经过GIS处理的、针对安徽省地图数据。ArcGIS是一款由Esri公司开发的专业地理信息系统软件,用于处理、分析和展示地理空间数据。MXD文件是ArcGIS的项目文件,包含了地图布局…

GitLab创建用户,设置访问SSH Key

继上一篇 Linux Red Hat 7.9 Server安装GitLab-CSDN博客 安装好gitlab,启用管理员root账号后,开始创建用户账户 1、创建用户账户 进入管理后台页面 点击 New User 输入用户名、邮箱等必填信息和登录密码 密码最小的8位,不然会不通过 拉到…

计算机网络--根据IP地址和路由表计算下一跳

一、必备知识 1.无分类地址IPV4地址网络前缀主机号 2.每个IPV4地址由32位二进制数组成 3. /15这个地址表示网络前缀有15位,那么主机号32-1517位。 4.地址掩码(子网掩码):所对应的网络前缀为1,主机号为0。 5.计算下…

重新整理机器学习和神经网络框架

本篇重新梳理了人工智能(AI)、机器学习(ML)、神经网络(NN)和深度学习(DL)之间存在一定的包含关系,以下是它们的关系及各自内容,以及人工智能领域中深度学习分支对比整理。…

Element-UI:如何实现表格组件el-table多选场景下根据数据对某一行进行禁止被选中?

如何实现表格组件el-table多选场景下根据数据对某一行进行禁止被选中? 在使用 Element UI 的 Table 组件时,如果你想要禁用某一行的选中(特别是在多选模式下),可以通过自定义行的 selectable 属性来实现。selectable …

WebRtc02:WebRtc架构、目录结构、运行机制

整体架构 WebRtc主要分为三层: CAPI层:外层调用Session管理核心层:包括视频引擎、音频引擎、网络传输 可由使用者重写视频引擎:编解码器、视频缓存、视频增强音频引擎:编解码器、音频缓存、回音消除、降噪传输&#x…

资源分享:gpts、kaggle、paperswithcode

gpts 似乎是gpt agent集合,专注于不同细分方向的ai助手。 kaggle 专注于AI相关的培训、竞赛、数据集、大模型。 paperswithcode 简单直接,内容如同网站地址,直接提供优秀代码和配套的论文,似乎还有数据集。

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度 一, PWM实现原理二,软件实现三,正点原子裸机开发总结 一, PWM实现原理 PWM和学习51时候基本上一致,控制频率(周期)和占空比,51实验…

Java 性能监控工具详解:JConsole、VisualVM 和 Java Mission Control

在 Java 应用程序的开发和维护过程中,性能监控和故障诊断是至关重要的。本文将详细介绍三款常用的 Java 性能监控工具:JConsole、VisualVM 和 Java Mission Control(JMC),并探讨它们的功能和使用方法。 1 JConsole 1…

一款好用的书签管理工具

多平台同步:可以在网页端、手机(iOS 和 Android)端同步使用。无论你是在电脑上浏览网页添加书签,还是在外出时使用手机,都能方便地访问和管理书签。例如,你在办公室电脑上收藏了一篇关于行业研究的网页&…

ansible-api分析(Inventory)

一. 简述: 通过ansible 实现系统初始化功能, 为和平台嵌入, 需要通过ansible的api进行功能实现。 准确来说,ansible并没有纯粹的外部接入api功能, 只是官方提供了原生类,用于继承接入,从而实现a…