【iOS】引用计数(一)

【iOS】引用计数

文章目录

  • 【iOS】引用计数
    • 前言
    • ARC与MRC
    • 什么是引用计数的机制
    • 内存管理的思考方式
      • 自己生成的对象
      • 非自己生成的对象
      • 不再需要自己持有就释放
      • 无法释放非自己持有的对象
    • autorelease
    • 小结

前言

笔者最近开始学习了一下有关于引用计数的内容,写这篇博客来简单认识一下引用计数部分的内容。

ARC与MRC

ARC就是自动引用计数,指的是OC中对于引用计数采取一个自动计数的方式。

在Objective-C中采用Automatic Reference Counting
(ARC)机制,让编译器来进行内存管理。在新一代Apple
LLVM编译器中设置ARC为有效状态,就无需再次键入retain或者release代码,这在降低程序崩溃、内存泄漏等风险的同时,很大程度上减少了开发程序的工作量。编译器完全清楚目标对象,并能立刻释放那些不再被使用的对象。如此来,应用程序将具有可预测性,且能流畅运行,速度也将大幅提升。

MRC则是由程序员手动进行内存管理,很显然ARC极大的提高了开发效率,也可以让程序更加流畅的运行。

什么是引用计数的机制

我们可以通过一个开关灯的思路去理解这部分内容,

在这里插入图片描述

正如上图所展示的,我们办公室在第一个人来的时候就要开灯,在最后一个人走后就要关灯,不能在当一个人走后就进行一个关灯操作,这样会影响其他人工作,所以只有当最后一个人离开办公室的时候再关灯就好了,这样才可以让其他人正常工作,而我们创建的对象可以理解为办公室里的照明设备,只要有一个人工作,照明设备就不可以被关闭。

OC中对应的一个状态对照明设备的操作
生成对象开灯
持有对象办公室还有人需要照明
释放对象不需要照明
废弃对象关灯

可以看到这里对象是否要被释放和我们这里办公室里面是否还有人关系非常密切,所以OC就采用了一种引用计数的方式来记录该对象是否要被释放,我们分析一下灯的开关被打开的几个过程,首先开始是没有人的状态这时候引用计数为0,后面有第一个人之后,引用计数为1,然后又来一个人引用计数为2,然后有人离去的时候引用计数减一,最后一个人离开的时候引用计数再减一,这时候我们就可以把这个灯关掉,这里我们把上述的灯改成对象,所以这里就简单介绍了我们对象的概念。

在这里插入图片描述

下面这张图就展示了我们的引用计数这个机制的几个步骤。

内存管理的思考方式

我们思考内存管理的时候,往往会过于关注计数这个问题,但是实际上计数反而不是重点,我们真正的应该思考的应该是如下四个方式来分引用计数。

  • 自己生成的对象,自己持有;
  • 非自己生成的对象,自己也能持有;
  • 不再需要自己持有的对象时释放;
  • 非自己持有的对象无法释放。

在这里插入图片描述
这个表格给出了OC中对应的操作。

自己生成的对象

id obj = [[NSObject alloc] init];id obj = [NSObject new];这两个都是自己生成对象自己持有。

我们按着驼峰命名法也可以来自己生成并且持有对象。

非自己生成的对象

我们使用出来非上述的方式也可以取得一个对象,但是因为不是通过自己生成并且持有的方式创建的,所以我们通过类似[NSMutableArray array]的方式创建的,我们还没有实现持有这个步骤,所以我们需要进行一个持有的过程.

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

这个方法的底层实现原理其实是通过一个autorealse这个方式来实现的,至于这个方法是如何实现的我们后面简单介绍一下。

id obj = [[NSObject alloc] init];
[obj autorelease];

这里就实现一个持有的操作,这里的对象并非自己创建但是仍然可以持有该对象。

不再需要自己持有就释放

简单来说就是我们不需要持有这个对象的时候,我们就需要调用release这个代码来实现一个释放的效果,比方说:

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

这里注意一下,如果一个对象一经释放就不可以再访问了。

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

在OC中我们也无法释放非自己持有的对象,举个例子:

id obj = [[NSObject alloc] init];[obj release];[obj release];

根据前面我们说的内容,这里我们如果已经release过一次,obj所持有的对象已经被废弃了,所以我们在释放一次的话就会出现一个程序崩溃的问题。

其实我们可以总结为以下四个方面:

在这里插入图片描述

autorelease

我们上面提到了autorelease,这里我们就来简单介绍一下有关autorelease的内容。

而autorelease是一种延迟释放对象的机制。当一个对象被autorelease时,它的引用计数不会立即减少,而是在当前autorelease pool被销毁时才会减少。
这意味着,即使你不再使用一个对象,它也不会立即被释放,而是等待当前Runloop结束时才会被释放。因此,autorelease可以在需要延迟释放对象时使用,以避免频繁释放和创建对象带来的性能开销。

在这里插入图片描述

他最大好处在于可以使取得的对象存在但是自己并不持有对象。

我们可以把它理解成一个C语言中的局部变量,C语言中的局部变量是在我们的变量超出自己的作用域的时候会被自动废弃,那么这里则是一个对象如果离开了autorelease的池中他会自己调用release这个方法。下面给出如何使用autorelsease,他有一优势就是我们可以定义变量的作用域。

在这里插入图片描述

这里我们按照上图的要求编写下面这段代码:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];id obj = [[NSObject alloc] init];[obj autorelease];[pool drain];NSLog(@"%lu", [obj retainCount]);//这里会报错,因为我们无法访问到这个对象

上面这段代码展示了我们如何使用autorelease这个方法,这里的[pool drain];相当于[obj release]

但是实际上我们的编译器会自己创建NSAutoreleasePool这个类的对象,就好比我们的NSMutableArray这个类

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];id obj = [NSMutableArray array];[obj autorelease];[pool drain];

这段代码会报错,主要原因是我们在创建NSMutableArray这个类的对象的时候,编译器会自动创建一个NSAutoreleasePool然后这个池子被放进了我们之前手动创建的NSAutoreleasePool这个池子中,所以他会把池子给释放,然后就会释放我们的数组,从而导致了我们的数组引用计数已经为0,导致代码报错。

小结

这里笔者对于引用计数进行了一个简单的学习,简单了解了他的一个相关实现,后面还会继续进行补充学习。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

关于自动化测试的一点了解

一 自动化测试基础的认识 1)首先,什么是自动化测试? 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的过程一步步执行测试,得到实…

史上最全!!!大厂面试真题-SpringBoot自动装配的原理是什么?

我想你也在真实面试中被问过无数次这个问题了,我也是,但是不管你怎么搜,都只有那几篇八股文的答案,你问GPT它都解释不清楚,我决定自己写一篇详细的,避免遗忘也想帮助一下患难中的兄弟姐妹们,能把…

struct的精确用法

目录 我终于回来啦! 1,可以创造根据结构体格式的成员或数组。 普通成员 数组成员 2,可以用指针遍历成员 3,使用typedef --------------------------------------------------------------------------------------------------------------------------------…

代码随想录Day 52|题目:101.孤岛的面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿

提示:DDU,供自己复习使用。欢迎大家前来讨论~ 文章目录 图论part03题目一:101.孤岛的总面积解题思路DFS**BFS** 题目二:102. 沉没孤岛解题思路 题目三:103. 水流问题解题思路优化 题目四:104.建造最大岛屿…

[Linux]用户管理指令

开机/重启/登录/注销 进入xhsell 或者虚拟系统中, 右键桌面打开终端, 在终端执行命令, 重启或关机linux系统 建议使用普通账号登录, 如果权限不够时, 使用 su - 用户名 命令切换到超管, 然后再使用 logout命令退回到普通账号, logout 不能在图形界面的终端中使用 用户管理 Li…

Centos7.9 使用 Kubeadm 自动化部署 K8S 集群(一个脚本)

文章目录 一、环境准备1、硬件准备(虚拟主机)2、操作系统版本3、硬件配置4、网络 二、注意点1、主机命名格式2、网络插件 flannel 镜像拉取2.1、主机生成公私钥2.2、为啥有 Github 还用 Gitee2.3、将主机公钥添加到 Gitee2.3.1、复制主机上的公钥2.3.2、…

最佳植树距离 - 华为OD统一考试(E卷)

2024华为OD机试(C卷D卷E卷)最新题库【超值优惠】Java/Python/C合集 题目描述 按照环保公司要求,小明需要在沙化严重的地区进行植树防沙工作,初步目标是种植一条直线的树带。由于有些区域目前不适合种植树木,所以只能在…

电脑提示找不到msvcp110.dll怎么办?全方面详细解答

msvcp110.dll 是 Microsoft Visual C 2012 Redistributable Package 中的一个动态链接库文件。它是运行使用 Visual C 2012 开发的应用程序所必需的,包含了许多 C 标准库函数的实现。这些函数主要用于支持字符串处理、内存管理、输入输出流、异常处理等功能。 1.ms…

Clion使用vcpkg管理C/C++包

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Clion安装vcpkg二、使用步骤1.切换到清单模式2.开始安装包 三、测试代码总结 前言 Linux上的库基本都可以通过apt或yum等包管理工具来在线安装包&#xff…

C语言深入理解指针(四)

目录 字符指针变量数组指针变量数组指针变量是什么数组指针变量怎么初始化 二维数组传参的本质函数指针变量函数指针变量的创建函数指针变量的使用代码typedef关键字 函数指针数组转移表 字符指针变量 字符指针在之前我们有提到过,(字符)&am…

NLP 文本分类核心问题

解决思路 分解为多个独立二分类任务将多标签分类转化为多分类问题更换 loss 直接由模型进行多标签分类 数据稀疏问题 标注更多数据,核心解决方案: 自己构造训练样本 数据增强,如使用 chatGPT 来构造数据更换模型 减少数据需求增加规则弥补…

MELON的难题- 华为OD统一考试(E卷)

2024华为OD机试(C卷D卷)最新题库【超值优惠】Java/Python/C合集 题目描述 MELON 有一堆精美的雨花石(数量为 n,重量各异),准备送给 S和 W,MELON 希望送给俩人的雨花石重量是一致的。请你设计一…

爬虫 ----hook

目录 定义: 了解什么是hook? 举例 hook XHR请求 XMLHttpRequest 案例地址: Interceptors-拦截器 HOOK cookie操作 cookie 示范 常见的hook代码总结 1.Hook Cookie 2.Hook Header 3.Hook URL 4.Hook JSON.stringify 5.Hook JSON.parse 6.Ho…

Mac使用gradle编译springboot-2.7.x源码

1 开发环境: JDK8 ideaIU-2024.2.2 gradle-7.6.3 代理网络 2 下载springboot源码 代码仓库网址 git clone -b 2.7.x https://github.com/spring-projects/spring-boot.git3 安装gradle gradle下载网址 https://services.gradle.org/distributions/ 安装此文件指…

C语言 | Leetcode C语言题解之第415题字符串相加

题目: 题解: char* addStrings(char* num1, char* num2) {int i strlen(num1) - 1, j strlen(num2) - 1, add 0;char* ans (char*)malloc(sizeof(char) * (fmax(i, j) 3));int len 0;while (i > 0 || j > 0 || add ! 0) {int x i > 0 ?…

lsof可以查看当前系统中正在被使用的文件,包括动态库

lsof的英文是 list open files lsof直接回车,会显示很多,可以配合more命令查看 lsof | more -10 sudo lsof | more -20 lsof查看正在使用某个动态库的进程 lsof /lib/x86_64-linux-gnu/libc.so.6 lsof /usr/lib/x86_64-linux-gnu/libc.so.6 l…

如何优化苹果CMS 泛目录的缓存管理?

在使用苹果CMS进行内容管理时,缓存管理是提升网站性能的重要环节。随着技术的不断发展,泛目录插件的缓存机制也逐渐变得不再必要。(maccmscn)本文将探讨如何在不使用缓存的情况下,优化苹果CMS泛目录的性能,…

(学习记录)使用 STM32CubeMX——配置时钟(入门)

使用STM32CubeMX配置STM32F103C8T6时钟部分 选择芯片 ①:选择MCU型号 ①:这里使用英文输入法,输入你想要的芯片型号,我这里采用STM32F103C8T6 ②:这里能看到搜索后出来的芯片具体型号,选择匹配度最高的一个…

MySQL-排名函数ROW_NUMBER(),RANK(),DENSE_RANK()函数的异同

MySQL-排名函数ROW_NUMBER(),RANK(),DENSE_RANK()函数的异同 前言 假设有如下表结构与数据,class_id表示班级,需求:现在要按照班级分组,每个班级的学生进行年龄从小到大排序 一、ROW_NUMBER()函数 ROW_NUM…

Linux中的调度算法

nice值的范围有限,即为[-20, 19],也就是40个数字,优先级为[60, 99]即一共40个优先级 目前谈论的Linux操作系统叫做分时操作系统,调度的时候主要强调公平,还有一种是实时操作系统,比如智能汽车里面必须装有这…