进击的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

相关文章

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Redis实现RBAC权限管理

《Redis实现RBAC权限管理》本文主要介绍了Redis实现RBAC权限管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1. 什么是 RBAC?2. 为什么使用 Redis 实现 RBAC?3. 设计 RBAC 数据结构

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Golang基于内存的键值存储缓存库go-cache

《Golang基于内存的键值存储缓存库go-cache》go-cache是一个内存中的key:valuestore/cache库,适用于单机应用程序,本文主要介绍了Golang基于内存的键值存储缓存库... 目录文档安装方法示例1示例2使用注意点优点缺点go-cache 和 Redis 缓存对比1)功能特性

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)