进击的KFC:OC(第九天):内存管理初级

2023-12-22 08:38

本文主要是介绍进击的KFC:OC(第九天):内存管理初级,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

⼀、内存管理介绍
内存的问题体现在两个方面:内存溢出,野指针异常
内存管理的⽅式:
垃圾回收(gc): 在OSX系统中用到
MRC(Manual Reference Count) // 手动引用计数
ARC(Auto Reference Count):自动引用计数
在ios开发过程中,用到的是引用计数的方法

⼆、内存管理机制
OC采⽤引⽤计数机制管理内存,当⼀个新的引⽤指向对象时,引⽤计数器就递增,当去掉⼀个引⽤时,引⽤计数就递减。当引⽤计数到零时,该对象就将释放占有的资源。

影响引⽤计数的⽅法:
+alloc : 开辟内存空间,让被开辟的内存空间的引⽤计数变为1。
这是由0到1的过程。-retain: 引⽤计数加1,如果内存空间之前引⽤计数为1,ratain之后变为2,如果引⽤计数是5,retain之后变为6
-copy : 把某⼀内存区域的内容拷⻉⼀份,拷⻉到新的内存空间⾥
去,被拷⻉区域的引⽤计数不变,新的内存区域的引⽤计数为1。-release : 引⽤计数减1,如果内存空间之前引⽤计数为4,release之后变为3,如果之前引⽤计数为1,release之后变为0,内存被系统回收。

-autorelease : 未来的某⼀时刻引⽤计数减1。如果内存之前引⽤计数为4,autorelease之后仍然为4,未来某个时刻会变为3。它是需要依托一个叫autoreleasepool自动释放池的,当调用autorelease的对像出了释放池的时候,释放池会给这些对象发送一个release的消息.

三、内存管理原则
引⽤计数的增加和减少相等,当引⽤计数降为0之后,不应该再使⽤这块内存空间。
凡是使⽤了alloc、retain或者copy让内存的引⽤计数增加了,就需要使⽤release或者autorelease让内存的引⽤计数减少。在⼀段代码内,增加和减少的次数要相等。

四、copy
-跟retain不同,⼀个对象想要copy,⽣成⾃⼰的副本,需要实现NSCopying协议,定义copy的细节(如何copy)。如果类没有接受NSCopying协议⽽给对象发送copy消息,会引起crash。

Person类copy⽅法的实现:
第一步:
Person.h⽂件
@interface Person : NSObject<NSCopying>
@property(nonatomic, retain)NSString *name;
@property(nonatomic, assign)int age;
@end第二步:
Person.m⽂件
@implementation Person
- (id)copyWithZone:(NSZone *)zone{Person *p = [[Person allocWithZone:zone]init];p.age = self.age;p.name = self.name;return p;
// copy方法 对引用计数的影响,要看你是怎么想的
//分为三种拷贝方法:// 1.伪拷贝:拷贝完还是那一个对象(直接返回)//return self; // 调用时 计数不变  ,// 2.浅拷贝:// 拷贝后,有两个对象,但是他们的值是同一个值,引用计数变 化,被拷贝的对象不变,拷贝出来的对象从0-1// Person *p =[[Person alloc]initWitnName:_name age:_age];// return p;// 3.深拷贝: 拷贝出新的对象, 并且 对象的值也重新拷贝一份,再赋值// 对字符串进行拷贝 拷贝的结果 要看字符串这个类如何实现的拷贝方法 对不可变字符串的拷贝相当于直接retain// 对可变字符串 拷贝时,就是真拷贝了一个新的出来//NSString *name = [_name copy];//Person *p = [[Person alloc] initWitnName:name age:_age];//return p;}第三步:
main.m⽂件
Person *p = [[Person alloc]init];
p.name = @”张三”;
p.age = 20;
Person *p2 = [p copy];
p2是p的副本。p2.name与p.name⼀样。p2.age与p.age⼀样。

总结:
1.OC借助引⽤计数机制去管理内存,凡是使⽤了alloc、copy、retain等⽅法,增加了引⽤计数,就要使⽤release和autorelease减少引⽤计数,引⽤计数为0的时候,对象所占的内存,被系统回收。

2.autorelease是未来某个时间(出autoreleasepool)引⽤减⼀,不是即时的。

3.不是任何对象都可以接收copy消息,只有接受了NSCopying协议的对象才能接收copy消息。

这篇关于进击的KFC:OC(第九天):内存管理初级的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/523302

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

用Microsoft.Extensions.Hosting 管理WPF项目.

首先引入必要的包: <ItemGroup><PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" /><PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /><PackageReference Include="Serilog

关于如何更好管理好数据库的一点思考

本文尝试从数据库设计理论、ER图简介、性能优化、避免过度设计及权限管理方面进行思考阐述。 一、数据库范式 以下通过详细的示例说明数据库范式的概念,将逐步规范化一个例子,逐级说明每个范式的要求和变换过程。 示例:学生课程登记系统 初始表格如下: 学生ID学生姓名课程ID课程名称教师教师办公室1张三101数学王老师101室2李四102英语李老师102室3王五101数学王老师101室4赵六103物理陈

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT

Android SurfaceFlinger——图形内存分配器(十一)

前面的文章中的图层合成器(HWC),这里我们接着看一下 SurfaceFlinger 中的另一个重要服务——图形内存分配器。 一、简介         android.hardware.graphics.allocator@2.0 是 Android 系统中硬件抽象层(HAL)的一个组件,专门用于图形内存的分配和管理。它是 SurfaceFlinger 在处理图形数据时所依赖的

逆向学习汇编篇:内存管理与寻址方式

本节课在线学习视频(网盘地址,保存后即可免费观看): ​​https://pan.quark.cn/s/3ceeb9ae6d98​​ 在汇编语言的世界中,内存管理和寻址方式是构建程序的基础。理解这些概念不仅对于编写高效的汇编代码至关重要,也是进行逆向工程分析的关键技能。本文将深入探讨内存管理的基本原则和多种寻址方式,并通过代码案例来展示它们的实际应用。 1. 内存管理 内存管理涉及如何分配

OC 中的*前const与*后const

int const *p2; int *const p3; 这个什么不能改由const后面的内容决定,如果是*p的话,则*p不可以改。 也就是说p指向的内容不能改变 如果const后面是p的话,则p不能改,也就是说p的指向不可以改变 OC中的字符串的话 NSString* name=@"wangning"; 此时我们不想让外界改变name的值得话const应该加在 NS

OC和 C语言中的const

const与宏对比 1.都是在其他的地方不可以改变 2.一个地方改了其他的地方都会改变。 而且宏定义的缺陷是, 是它会不断的开辟临时变量的存储空间 使用const的话 是都去使用同一的一份空间,使用同一个对象。 加const 之后变量还是全局的,只不过变为全局常量。 如果此时改变量不想被被类外面访问的话,可以加上static关键字, 3.下次想要定义一些宏的时候分