[iOS] OC高级编程 - 引用计数 (1) - 详解

news/2025/9/26 13:10:30/文章来源:https://www.cnblogs.com/ljbguanli/p/19113287

[iOS] OC高级编程 - 引用计数 (1) - 详解

[iOS] OC高级编程 - 引用计数 (1)

前言

引用计数是 iOS 开发中非常重要的一部分内容,仅以本篇博客做此记录,以及介绍引用计数。

ARC 与 MRC

iOS下内存管理的基本思想就是引用计数,通过对象的引用计数来对内存对象的生命周期进行控制。具体到编程时间方面,主要有两种方式:

1:MRC(manual retain-release),人工引用计数,对象的生成、销毁、引用计数的变化都是由开发人员来完成。

2:ARC(Automatic Reference Counting),自动引用计数,只负责对象的生成,其他过程开发人员不再需要关心其销毁,使用方式类似于垃圾回收,但其实质还是引用计数。

引用计数机制

书里有这么一个思路我们可以去理解这部分内容

请添加图片描述

就是通过照明设备来比喻,如果把对象比作照明设备,对象的使用环境就相当于上班进入办公室的人,如上图所演示的来的第一个人就要开灯,走的最后一个人就要关灯,只要有一个人工作,照明设备就不可以被关闭。

请添加图片描述

这个比喻也是非常形象的,它同时还可以表示那一个被计数的过程,首先开始在没有人的状态下时引用计数为 0,后面有第一个人后,引用计数为 1,然后再来一个人引用计数为 2,在有人离开时引用计数减一,最后一个人离开时再减一,这时灯就被关掉了。类比到对象就是对象被废弃掉了。

请添加图片描述

上面这张图就详细展示了这个引用计数的几个步骤。

内存管理的思考方式

有关于引用计数,正确的思考方式有四条准则:

自己生成的对象自己持有

使用 alloc,new,copy,mutablecopy 这几个开头的方法名意味着自己生成的对象自己持有。

就比如这段代码

// 自己生成并持有对象
id obj = [[NSobject alloc] init];

使用 NSObject 的类方法就能自己生成并持有对象,指向生成并持有对象的指针被赋给变量 obj。同时 new 类方法也能生成并持有对象。

copy方法基于NSCopying方法约定,由各类实现的copyWithZone:方法生成并持有对象的副本,mutableCopy也一样,二者区别只在于生成的对象是否可变。这些方法生成的对象,虽然是对象的副本,但也属于“自己生成并持有对象”。

非自己生成的对象,自己也能持有

用除了上面介绍的(alloc/new/copy/mutablecopy 以外的方法)获得的对象,因为并非自己生成,所以自己并不是该对象的持有者。

id obj = [NSMutableArray array];

在下面这段代码中,NSMutableArray 类对象被赋给变量 obj,但是变量 obj 自己并不持有该对象,使用 retain 方法可以持有该对象。

//取得非自己生成并持有的对象
id obj = [NSMutableArray array];
//取得的对象存在,但自己不持有对象
[obj retain];
//自己持有对象

不需要自己持有的对象时释放

自己一旦不再需要自己持有的对象,那么持有者就有义务去释放该对象,使用 release 方法。

id obj = [[NSObject alloc] init];
[obj release];
//对象一经释放绝对不可访问

这样对象就被 release 方法释放掉了,自己生成而非自己持有的对象,如果使用 retain 变成自己持有的,同样可以 release 释放。

id obj = [NSMutableArray array];
[obj retain];
[obj release];

如果要使用某个方法生成对象,并将其返还给该方法调用方

- (id)allocObject {
id obj = [[NSObject alloc] init];
return obj;
}

如上例,将用alloc方法生成的对象直接返回。就能让调用方也持有该对象。注意,这里与上文命名规则相符合,使用allocObject也就意味着“自己生成并持有对象”那像[NSMutableArray array]这种方法使取得的对象存在,但自己不持有对象,又是如何实现的呢?根据上文规则,不能使用alloc/new/copy/mutableCopy开头的方法名,因此我们使用object这个方法名

- (id)object {
id obj = [[NSObject alloc] init];
[obj autorelease];
//取得对象存在,但自己不持有对象
return obj;
}

在这里我们用到了 autorelease 方法,用这个方法可以使对象存在,但自己不持有对象。
请添加图片描述

无法释放非自己持有的对象

自己持有的对象释放完以后不需要再次释放。

id obj = [[NSObject alloc] init];
[obj release];
[obj release];
//应用程序崩溃!
//访问已经废弃的对象时崩溃

或者取得的对象存在,但自己不持有对象时释放

id obj1 = [obj0 object];
//取得对象存在,但自己不持有
[obj1 release];
//程序崩溃

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker Docker Compose 完整入门与实用技巧 - 教程

Docker & Docker Compose 完整入门与实用技巧 - 教程2025-09-26 13:10 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important;…

建网站过程网站制作报价优惠

[html] 说说你对属性data-的理解 data- 属性是H5新增的自定义属性,也可以用来存储值。我个人用的不多,这个data- 属性倒是和vue中的v-bind 功能相似, 自定义属性,绑定数据。也和上面说的一样可以通过js进行获取使用个人简介 我是…

营销型网站建设合同戚墅堰做网站

云原生之使用Docker部署RSS阅读器Huntly 一、Huntly介绍1.1 Huntly简介1.2 Huntly功能2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Huntly镜像五、部署Huntly5.1 创建挂载目录5.2 创建Hun…

达州网站建设的公司怎么自己搭建梯子

最近在练习搭建网站,遇到游览器找不到服务器上的php文件的问题。后来查找发现,apache文档根目录跟apache虚拟主机文档根目录不同,服务器开启了虚拟主机功能。这导致游览器找不到php文件。 使用的环境是LAMP,它 的操作系统和软件版…

西安网站建设公司电话wordpress 删除 评论

事件以及事件相关的兼容性问题 事件最早是在 IE3 和 Navigator2 中出现的,当时是作为分担服务器运算负担的一种手段。要实现和网页的交互,就需要通过 JavaScript 里面的事件来实现。 每次用户与一个网页进行交互,例如点击链接,按下…

网站模板兼容手机端灰色推广引流联系方式

文章目录 📄前言一. Mybatis简介✈️1. 什么是Mybatis🚀2. 为什么使用Mybatis 二. Mybatis快速入门🍆1. mybatis使用前准备1.1 创建springboot项目并引入相关依赖1.2 在 application.ym中进行数据源的配置1.3 创建数据表,准备表数…

杭州网站建设哪个好想创建一个网站

🌼未封装 在项目中往往一个页面存在着要联调好几个接口,此时用下面的写法就会显得代码很冗余 // 向给定ID的用户发起请求 axios.get(/user?ID123456,{ params: { //发送请求的数据ID: 123456 } }) .then(function (response) { // 处理成功情…

网站详情页用什么软件做如何制作自己的网站模版

理解依赖属性 依赖属性支持的特征包括:动画、数据绑定、样式。由WPF元素暴露的属性大部分都是依赖属性。依赖属性和常规属性的使用方法相同。 WPF设计了依赖属性支持其特有的动态特性,并且不干扰其他系统的.net代码。 定义依赖属性 创造一个依赖属性的语…

PySide6 之鼠标事件写字板

一、效果图二、示例代码from PySide6.QtWidgets import * from PySide6.QtCore import * from PySide6.QtGui import * import sysclass ImageWidget(QWidget):pass鼠标控制图片缩放、拖动,鼠标滚动放大、缩小 class …

深入解析:golang基础语法(三)常量、指针、别名、关键字、运算符、字符串类型转换

深入解析:golang基础语法(三)常量、指针、别名、关键字、运算符、字符串类型转换pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; fo…

烟台网站建设方案成都市建设局官方网站

目录 一. 空属性null 二. 默认值default 三. 列描述comment 四. 填充零zerofill 五. 主键primary key 六. 自增长auto_increment 七. 唯一键unique 八. 外键foreign key 一. 空属性null 对于表中的数据,如果在进行插入的时候不显示地给定值,那么…

单B细胞技术如何实现兔单抗高通量高特异制备

单B细胞技术如何实现兔单抗高通量高特异制备 在单克隆抗体(mAb)研发领域,兔源单抗以其高亲和力和高特异性备受关注。传统的杂交瘤技术虽然成熟,但周期长、效率低,而且抗体多样性有限。近年来,单B细胞技术的出现,…

HP激光墨盒换墨粉

墨盒分区加墨是先清理使用过的墨粉,在加入要使用的墨粉。 清理使用过的墨粉 可拆开使用过的墨粉的墨盒去清理,也可用不拆下清理。打开红色框的盖子,到出里面的墨粉,最好用袋子装好清理,防止粉尘到处飞。 拆下来清…

实用指南:Golang学习笔记: 常用标准库

实用指南:Golang学习笔记: 常用标准库pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mo…

AI论文速读 | 当大语言模型遇上时间序列:大语言模型能否执行多步时间序列推理与推断 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

unordered_map性能被吊打!我用基数树让内存池性能暴涨几十倍的秘密

哈喽,大家好,我是小康! 今天要和大家聊一个特别有意思的话题——基数树。 说实话,我第一次听到这个名词的时候,内心是懵逼的。基数?树?这玩意儿到底是啥? 直到有一天,我在研究TCMalloc内存池源码的时候,发现…

网站备案后可以更换域名吗网红营销优势

Title 题目 Automated anomaly-aware 3D segmentation of bones and cartilages in kneeMR images from the Osteoarthritis Initiative 来自骨关节炎计划的膝关节MR图像的自动异常感知3D骨骼和软骨分割 Background 背景 近年来,多个机器学习算法被提出用于图像…

asp网站配置伪静态重庆注册公司核名在哪个网站

上次提到的开机自启动的配置,获得了LD的称赞,然而LD的要求,都是“既得陇复望蜀”的,他又期望我们能实现openGauss安装的“自动化”,于是尝试了下用shell脚本部署,附件中的脚本实测有效,openEule…

详细介绍:《 Linux 点滴漫谈: 一 》开源之路:Linux 的历史、演进与未来趋势

详细介绍:《 Linux 点滴漫谈: 一 》开源之路:Linux 的历史、演进与未来趋势pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fa…

深入解析:TENGJUN“二合一(2.5MM+3.5MM)”耳机插座:JA10-BPD051-A;参数与材质说明

深入解析:TENGJUN“二合一(2.5MM+3.5MM)”耳机插座:JA10-BPD051-A;参数与材质说明pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important…