当前位置: 首页 > news >正文

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

[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.gsyq.cn/news/12222.html

相关文章:

  • AI论文速读 | 当大语言模型遇上时间序列:大语言模型能否执行多步时间序列推理与推断 - 指南
  • unordered_map性能被吊打!我用基数树让内存池性能暴涨几十倍的秘密
  • 深入解析:TENGJUN“二合一(2.5MM+3.5MM)”耳机插座:JA10-BPD051-A;参数与材质说明
  • CentOS 9服务器版 部署Zabbix7.0 server端 - 详解
  • US$189 VVDI2 BMW FEM amp; BDC Functions Authorization Service With Ikeycutter Condor
  • 模式组合应用-享元模式 - 详解
  • Go 1.26 内置函数 new 新特性
  • 重要公式 - Emi
  • 软件构造中的数据处理(sql) 6章
  • Gitee vs. GitLab:中国开发者为何选择本土代码托管平台?
  • US$39 BAV-Key Adapter for Yanhua Mini ACDP
  • 级数 - Emi
  • 基于STM32的正弦波逆变器设计
  • 深入解析:SDL2视频渲染
  • 使用Ollama 0.12.2本地部署大模型,友好界面对话,开启飞行模式数据完全存在本地
  • 详细介绍:四大金刚之计算机网络
  • 物联网字节校验常用方法
  • 实用指南:RabbitMQ 核心组件详解与持久化日志队列实现方案
  • 完整教程:Zookeeper与Kafka:分布式系统中的协调与消息队列
  • 外发图纸如何控制的最佳实践与注意事项
  • Gitee:中国开发者生态的数字底座正在重构技术格局
  • 文件同步软件是什么?主要有哪几种类型?
  • “铸网2025”山东省工业和互联网CTF竞赛-web
  • 全球知名的Java Web开发平台Vaadin上线慧都网!
  • C#实现与欧姆龙PLC通信
  • 什么是跨网文件摆渡系统?IT运维效率提升300%的秘密武器
  • 借助Aspose.Email,在 Python中创建事件日历
  • C++ map 和unordered_map 的区别
  • Kubernetes Cilium网络组件和CoreDNS配置
  • 题解:P10107 [GDKOI2023 提高组] 树