OC的内存管理引用计数机制

来源:互联网 发布:php小数转换为整数 编辑:程序博客网 时间:2024/05/10 20:57

我们知道,程序在堆区的内存管理需要程序员手动来分配及回收,什么时候分配,什么时候回收,这就是内存管理了。

苹果的OC语言,对于内存管理是用一种叫做引用技术机制的管理方式,说简单点就是给这块内存空间挂一个写着整数的牌子,当牌子上的数字不为0时,这块内存地址就不回收,程序员可以用alloc,retain,release,autorelease,对这个牌子上的数字进行增减。在IOS5之前,这件事都是由程序员来处理的。

引用计数机制的原则就是,谁污染谁治理,谁增加引用计数,谁就要去减引用计数。

听起来好像很简单,但是实际操作起来,一个控制器里大量retain,release,看的很碍眼,而且在比较庞大的项目里,程序员还要绞尽脑汁的考虑到底在哪里释放才不会内存泄露,才不会出现过度释放,才不会有野指针。大量的精力耗费在管理内存上,于是从IOS5开始,苹果推出了一个新功能:自动内存管理(ARC),这是和之前手动内存管理(MRC)相对应的。

ARC并非是把引用计数机制去掉了,编译器帮程序员做了写retain,release等的相关工作,编译的时候,编译器自动在相应部位加上这些代码。

接下来解释一下一些概念:

1、内存泄露:就是开辟了一块内存空间,使用完之后,没有释放,这样这块空间就一直被占用着,白白浪费了。举个例子就是,甲和乙从图书馆图书管理员那借了一本书(当场翻阅的那种),这样这本书的引用计数就为2,甲看完之后,告诉图书管理员,我看完了,书的引用计数减1,这个时候甲也看完了,但是他没有告诉管理员他不看了,而是拍拍屁股就走了,图书管理员也不知道这本书甲不看了,以后甲一直在看。如果这个时候丙来借书,图书管理员只能借另外一本给他。这样这本书就一直扔在那边,如果书是内存空间,这样就是内存泄露了。

2、野指针:我们做内存管理的经常做,释放对象,要把指针置空,防止野指针。举个例子就是,甲和乙又去借了一本《oc大全》,书的引用计数为2,乙的记性不好,他不看书了,连续跟管理员说了两次,我看完了,管理员以为是甲和乙都不看了,就把书给收走了,甲在玩手机,也没注意手机被收走,等他回过神来要看书的时候,发现桌上的书变成了《毛邓理论》,这个就是野指针,野指针最大的危害就是指向不可预料的区域。

3、过度释放:过度释放就是如上面野指针的那个例子,乙只增加了1的引用计数,缺减了2的引用计数,所以违反了原则,多释放了一次,就是过度释放。

4、延迟释放:有一种情况,就是甲要帮乙借书,但是他们人不在一起,甲先去图书馆把书借出来了,但是乙还没到,甲又有事急着走,甲就告诉图书管理员,这书我还要看1个小时,之后就不看了,然后把书扔桌上走了,图书管理员开始倒计时,过了20分钟,乙来了,然后告诉管理员,这书我要看,这个时候书的引用计数为2,1个小时过去了,图书管理员要去回收书,书的引用计数减1,结果一查,还有个乙在看书,引用计数为1,于是就不会回收书。

在OC里的延迟释放是用autorelease来实现,对象调用了autorelease并不会马上减引用计数,而是被加入一个叫自动释放池的地方,当自动释放池被释放的时候,池子里的对象都引用技术减1。这里注意,是引用计数减一,而不是被释放。

至于有的新手说,为啥指针啊,局部变量那些不用释放,因为那些是存放在栈区里的,一个大括号走完,生命周期也就结束了,自动出栈。栈区的内存管理不需要程序员手动管理。

0 0