您的位置:首页 > 移动开发 > Objective-C

[ObjectC]Objective-C内存管理机制

2016-05-12 02:34 447 查看
Objective-C继承自C,拥有一套基于对象引用计数的内存管理体系。这跟C#或者Java的垃圾回收机制不同,倒是与C++后来的智能指针有些类似。这种引用计数的思想在很多地方也有应用,不过本质上说,仍然是需要程序员来手动管理计数的,只不过当计数值清零时,对象会被自动释放罢了。

Objective-C中提供了两种内存管理机制:MRC(MannulReference Counting-手动引用计数)和ARC(Automatic
Reference Counting-自动引用计数)
,分别提供对内存的手动和自动管理,来满足不同的需求。现在苹果推荐使用ARC
来进行内存管理。引用计数(retainCount)是Objective-C管理对象引用的唯一依据。

Objective-C内存管理机制 

OC中每个对象都有一个与之对应的整数,叫“引用计数器”,当一个对象在创建之后它的引用计数器值加1,当调用这个对象的alloc、retain、new、copy方法之后引用计数器值自动在原来的基础上加1,当调用这个对象的release方法之后它的引用计数器值减1,如果一个对象的引用计数器值为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。 

MRC

对象操作的四个类别

对象操作

OC中对应的方法

对应的 retainCount变化

生成并持有对象

alloc/new/copy/mutableCopy等

+1

持有对象

retain

+1

释放对象

release

-1

废弃对象

dealloc

-

 

在MRC的内存管理模式下,与对变量的管理相关的方法有:retain, release
和 autorelease。retain
和 release
方法操作的是引用记数,当引用记数为零时,便自动释放内存。并且可以用
NSAutoreleasePool
对象,对加入自动释放池(autorelease
调用)的变量进行管理,当
drain 时回收内存。

 

ARC

ARC 是苹果引入的一种自动内存管理机制,会根据引用计数自动监视对象的生存周期,实现方式是在编译时期自动在已有代码中插入合适的内存管理代码以及在Runtime
做一些优化。

变量标识符

在ARC中与内存管理有关的变量标识符,有下面几种:

__strong 是默认使用的标识符。只有还有一个强指针指向某个对象,这个对象就会一直存活。
__weak 声明这个引用不会保持被引用对象的存活,如果对象没有强引用了,弱引用会被置为nil
__unsafe_unretained 声明这个引用不会保持被引用对象的存活,如果对象没有强引用了,它不会被置为nil。如果它引用的对象被回收掉了,该指针就变成了野指针。
__autoreleasing 用于标示使用引用传值的参数(id *),在函数返回时会被自动释放掉。

自动释放池

后来开始出现自动释放池(Auto release pool),这个东西的出现简单的说是基于一种十分常见确很难处理的场景:需要在一个方法内部申请内存,并将内存的地址返回给调用者,这个时候谁来释放这个内存?如下面的代码:

-(ClassA *) Func1
{
//内部申请空间,obj引用计数为1
ClassA *obj = [[ClassA alloc] init];
//返回这个申请的内存
return obj;
//谁来负责释放???
}


这个梗其实在任何非垃圾回收的语言中都存在,需要人为约定,要么创建者释放,要么调用者释放。试想,如果是创建者释放,那么创建者怎么知道调用者什么时候结束调用呢?如果是调用者释放,又会因为协同开发的原因,造成调用者忘记释放的情况。

OC发明了自动释放池的概念,上面的代码可以这样写:

-(ClassA *) Func1
{
//内部申请空间,obj引用计数为1,使用autorelease延迟释放
ClassA *obj = [[[ClassA alloc] init] autorelease];
//返回这个申请的内存
return obj;
}


使用autorelease方法,实际上的结果是本地变量obj的引用在自动释放池中保留一份,并在恰当的时候,释放掉.

参考:

Objective-C中的内存分配Objective-C中的内存分配

Objective-C内存管理的历史和参考资料
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: