码迷,mamicode.com
首页 > 移动开发 > 详细

iOS内存管理

时间:2015-04-05 23:31:13      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:

内存管理就是确保开辟的堆空间被正确的释放。如果堆空间没有释放,称为【内存泄露】使用已经释放的空间,称为【提前释放】重复释放同一个空间,称为【重复释放】

(1)当我们要释放一个堆,首先要确定使用这个堆的指针,都访问完毕。避免提前释放。

(2)释放指针指向的堆空间,首先要确定哪些指针指向同一个堆,这些指针,只能释放一个。避免重复释放。

(3)模块化操作,哪个模块负责释放,将成为巨大的难题。

(4)多线程操作,无法确定哪个线程最后使用完毕。

【结论】OC的内存管理,就是在编写程序时,保证计数器的数值和使用对象指针数相同,保证计数的增加和减少次数相同。?

【手动内存管理MRC】

一.关闭ARC

//工程 —> Targets —> BuildSetting —> 搜索【gar】

【YES】—>【NO】

NSObject:

- (id)retain;//引用计数加1

- (void)release;//引用计数减1 理论上减到0释放,原则上一个指针只能发送该消息一次

- (NSUInteger)retainCount;

//返回对象的当前引用计数

Δ二.内存管理的法则

1.凡是用alloc,retain,new(或使用new开头的方法),copy(或使用copy开头的方法),mutableCopy(或使用mutableCopy开头的方法)【创建】的对象,都必须使用release或autorelease方法【释放】

Δ2.谁创建谁释放(哪个类创建,哪个类释放;谁写alloc,谁写release)。

【注意事项】

1.对象的成员变量在构造方法中创建,应在析构方法中释放。

2.注意指针的转移 释放旧对象 保留新对象。

3.从数据结构如数组中取出对象地址,如果需要长时间使用,应当retain。

【相关方法】

copy 和 mutableCopy:只用来复制字符串

new

[Dog new] <==> [[Dog alloc] init];

三.自动释放池

@autoreleasepool{

@autoreleasepool{

}

}

NSAutoreleasePool

//自动释放池原本也是对象,为了配合ARC改成了关键字。

- (id)autorelease;

//自动释放/ 延迟释放

【注】自动释放池类似一个数组,进行延迟释放,不会马上计数器减1,而是将当前对象,放入最近的自动释放池。当池释放时,将每个池中的元素释放一次。

【注】在iOS程序中,每个触发周期,都会创建并销毁一个自动释放池。

【自动释放原则】

1.方法的局部变量可以使用自动释放。

2.非用自动释放不可的情况

【结论】只有一个函数中使用的对象,可以使用类方法创建。

四.相关工具

product —> profile —> leaks

【自动内存管理ARC】

//从Xcode5以后,默认自动内存管理

automatic reference counting;

//自动引用计数

【提】简单点说就是让编译器完成堆空间的引用计数加减,自动释放。程序员不再写 retain release等方法

【另】OC的自动内存管理,不同于JAVA垃圾回收。而是在预处理时,直接在应该保留的地方,添加retain,在应该释放的地方,添加release。是直接添加代码。

【另】从效率上,ARC优于手动内存管理。

一.ARC的局限

1.使用ARC,可能因为代码的不规范,导致内存提前释放。

//尤其使用AVAudioplayer类的时候,很可能造成提前释放。

2.导入一些第三方库,或者导入旧代码,这些代码不支持ARC。

二.解决ARC的局限

1.将不使用ARC的代码转成ARC代码

Edit —> Refactor —> Convert to ARC

2.ARC非ARC混编

//同一个工程中,部分文件使用ARC,部分文件不使用ARC。

Build phase -----> Complie Source

-fno-objc-arc

三.使用ARC的技巧

1.四个关键字 修饰引用

__strong(强引用) 缺省属性,其修饰的对象指针,指向哪个对象,会对该对象retain,离开哪个对象,会对该对象release。

__weak(弱引用)其修饰的对象指针,指向任何对象都不会retain。这样的指针指向的对象随时可能消失。如果对象消失了,这个指针会自动变成nil。

//在iOS编程中,代理对象使用弱引用。

__unsafe_unretained 其修饰的对象指针,指向任何对象都不retain。当指向的对象消失,该指针不会变成nil,仍然指向已经释放的对象

__autoreleasing 只用来修饰需要被传入地址的指针。如:

__autoreleasing NSError * error;   &error;

2.属性的()参数,原则上,不能写retain copy了,只能写Strong,如果不想retain,写Weak

【注】但实际上ARC对这方面很宽松,谢了retain也没关系。

3.id 指向对象,不能用void * p指向对象。

int a;

void * p = &a;

id p = [[NSObject alloc] init];

4.C的结构体中,不能声明对象指针。否则这个指针不会进行内存管理

struct sct{

id obj;

};

5.不能(显式)手动调用父类的dealloc

-(void)dealloc

{

self.name = nil;

//自动调用父类的dealloc

}

iOS内存管理

标签:

原文地址:http://www.cnblogs.com/MarkBlog/p/4394932.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!