您的位置:首页 > 职场人生

黑马程序员_MRC2

2015-11-10 12:04 260 查看

MRC

上次blog我谈到iOS MRC内存管理的原理、原则以及出现的问题,接下来我会结合实例继续介绍在处理MRC内存管理的时候经常出现的问题:内存泄露、循环引用(retain)

一、内存泄露:

内存泄露的主要原因在于,没有遵守内存管理的原则,要么忘记release,要么release的次数少了。下面通过代码展示:

<span style="font-family:Comic Sans MS;font-size:18px;">//第一种情况
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建car对象
Car *car=[Car new];
}
return 0;
}</span>
分析:指针变量car存在栈区,是一个临时变量,在程序执行到其作用域({})外时会自动销毁。但是,在堆区的对象需要手动回收,而指向这片内存的指针已经被销毁,我们在这个程序结束以前,是没有办法回收该对象的内存的。这就造成了内存泄露。

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="color:#000066;">//第二种情况
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建car对象
Car *car=[Car new];
car=nil;
[car release];
}
return 0;
}</span></span>
分析:指针变量car被重设为nil,但堆区内存并没有释放,我们也无法再次获得该对象的内存地址,造成内存泄露。

<span style="font-size:18px;">//第三种情况
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建car对象
Car *car=[Car new];
[car retain];
[car release];
}
return 0;
}</span>

分析:对象被retain了一次或多次,但只是release了一次或少次,在出了指针的作用域后,对象无法释放。
注:对象被retain了,有时候并没有这么明显,可能在调用函数的时候被retain或copy等。

对于内存泄露,并没有一劳永逸的方法,只能靠自己的写代码的时候,多加注意,严格遵循内存管理的原则。

二、循环retain

 循环引用是一个很经典的问题,我以前在学c++的时候,就遇到过,C++通过强弱指针解决这个问题,当然本质上C++的智能指针也是通过引用计数解决问题。下面我通过一个实例来看一下OC在MRC模式下如何处理这个问题。

//main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Dog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建人对象
Person *lele=[Person new];
//创建狗对象
Dog *wangcai=[Dog new];
//将人的狗设为
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: