时间:2017-6-15来源:本站原创作者:佚名

作为一个有志向的程序员,在开发的早期就应该养成清理内存的习惯。

我从三个方面来谈一谈对iOS开发中内存管理的认识。

一,iOS内存管理中需要理清的问题

1,内存管理的主体。

内存管理是针对oc的对象,与基础类型无关,比如int、float等。ARC环境下编译器会自动对oc对象插入rtain、rlas。但是CorFoundation对象需要我们手动来管理。Appl提供了__bridg、__bridg_transfr、__bridg_rtain三个关键字给我们,__bridg用来做类型转换,不涉及到所有权转移,__bridg_transfr用来将cf对象所有权转移到oc对象,__bridg_rtain用来将oc对象所有权转移到cf对象,之后就要手动使用CFRlas来销毁对象。

2,对象的创建方式

Prson*p=[[Prsonalloc]init];

oc中所有对象都是在堆区中分配内存空间的。我们知道在堆区中分配的内存空间都是需要程序员手动管理的。

3,引用计数

oc提供引用计数的方式来让程序员管理内存。引用计数从字面来说就是记录引用的次数,在oc里面一个strong指针指向一个对象的存储空间称为一次引用。在对象的传递过程中,会出现多个strong指针指向一个对象的存储空间。(大家想想引用计数的优点是不是达成了内存空间的共享)oc语言保证,在对象的引用计数为0的时候,会自动调用该对象的dalloc方法,回收对象的内存空间。

4,引用计数器存放位置

在给对象分配内存空间的时候,会单独的分配一块存储空间用来存放该对象的引用计数器。即引用计数器是放在对象的存储空间中。

5,引用计数的变化场景

在对象赋值、参数传递的过程中都会发生引用计数的变化。对象引用计数的变化原则是释放旧对象保留新对象。

6,全局对象vs局部对象

这里对象指的是操作对象内存的句柄(指针)。当一个对象作为全局的时候,显然生命周期是与其宿主对象绑定在一起的,当宿主对象的dalloc被调用的时候,会对所有的全局对象做一次rlas。编译器对全局对象和局部对象会正确的插入rlas操作的。

7,循环引用

引用有单向引用,也有双向引用。当A对象和B对象互相引用的时候,就出现了循环引用。循环引用会导致互相引用的对象均不能被销毁。项目里面的内存泄漏问题大多都是循环引用导致的。常见的导致循环引用发生的是block,但是并不是所有的block都会导致循环引用,一定要注意产生循环引用的条件(互相引用)。当然有些时候是在不清楚的情况下,导致产生了循环引用,比如使用了一些第三方的类。

二,做好内存管理的标准

黄金法则:确保每个对象的dalloc被调用。这里面有一个容易理解错的点,当一个对象的dalloc被调用的时候,会对所有的对象成员变量执行一次rlas操作,仅此而已。并不是说对象的dalloc被调用,其对象成员变量的dalloc也被调用。

三,项目中一个忽视的内存管理问题

大多数APP都会基于AFN来封装网络请求类。封装的策略有两种,一种是用单例,另一个是用对象的方式。采用单例的方式只会初始化一次AFHTTPSssionManagr对象,但是这种方式会局限NSURLSssion,因为只能设置一次NSURLSssionConfiguration。采用对象的方式则可以每次初始化的时候有机会变更NSURLSssionConfiguration,更加灵活一点。

当我们使用对象的方式来使用网络请求类,如果不在dalloc的方法里面做下面的操作,将会导致内存泄漏。

之所以会到导致内存泄漏,是因为NSURLSssion和AFHTTPSssionManagr是一个循环引用的关系。invalidatSssionCanclingTasks这个方法就是用来解除循环引用关系的。

附录:使用AFN的方式和优缺点









































治疗白癜风应到北京那家治最好
小孩白癜风能治好吗

转载请注明原文网址:http://www.gzdatangtv.com/cksc/7158.html
------分隔线----------------------------