一、内存管理
1. 为什么要进行内存管理
移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多是,系统就会发出内存警告,每个app可以用的内存是被限制的,如果内存超过20M,系统就会对该APP发出Memeory Warning消息。收到此消息需要回收一些不需要继续使用的内存空间。
2. OC内存管理范围
管理范围:管理任何继承NSObject的对象,对其它类型基本无效。对象类型是程序运行过程中动态分配的,存储在堆区的内存管理主要是对堆区中的对象的内存管理。
只有OC对象才需要进行内存管理的本质原因:
OC对象存放于堆里面,
非OC对象一般放在栈里面(栈内存会被系统自动回收)。
3. 对象所有权:任何对象可以拥有一个或多个所有者。只要对象拥有一个所有者,它就会继续存在。
Cocoa所有权策略:任何自己创建的对象都归自己所有,可以使用名字以“alloc” 或 “new”开头或名字中包含“copy” 的方法创建对象,可以使用retain来获取一个对象的所有权。
4.
引用计数器
1)每个OC对象都有自己的引用计数器,是一个整数(8字节)表示对象引用的次数,即现在有多少东西在使用这个对象。对象刚被创建是,默认计数器值为1,当计数器的值为0时,则对象销毁。
2)作用:引用计数器是判断对象要不要回收的依据(存在一种例外:对象值为nil时,引用计数器为0,但不回收空间),就是计数器是否为0。
3)操作:给对象发消息,进行相应的计数器操作
retain:使计数器+1,该方法返回对象本身。
release:使计数器-1
retainCount:获取对象当前引用计数器的值 %ld %tu(无符号长整型)
4)对象销毁:当一个对象的引用计数器为0是,那么它就会被销毁,其占用的内存也就会被系统回收。
当对象销毁时,系统就自动会给对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源。
一旦重写了dealloc方法,就必须调用[super dealloc] ,并且放在代码块的最后调用
一旦对象被回收了,那么它的存储空间就不再可用,强制使用会导致程序崩溃(野指针错误)
5. OC内存管理分类:
MRC 手动管理 ,ARC 自动引用计数,garbage collection(垃圾回收,iOS不支持)
6. 内存管理的原则:
1)原则:
只要还有人使用某个对象,那么这个对象就应该被回收
只要你想使用这个对象,那么就应该让这个对象的retain引用计数器+1
当你不想使用这个对象时,那就就应该让这个对象release(引用计数器-1)
注意:谁创建谁release,谁retain谁release
7.内存管理研究的内容:
1)野指针:定义指针没有进行初始化,指向的内存空间被释放
2)内存泄漏:Person *p = [Person new]; 栈区空间p释放了,但是堆区[Person new]没有被释放,那么堆区空间就被泄漏了
3)僵尸对象就是:对象的空间已经释放掉了,Xcode默认是不检测僵尸对象。
8. nil是一个对象的值
NULL是一个通用指针
NSNul 是一个对象,他不能使用nil的场合
9. 单个对象内存管理
1)泄漏问题:
创建完成后,使用后没有使用release
没有遵守内存管理原则
不当使用nil
2)避免使用僵尸对象的方法:将对象赋值nil
10. 多个对象内存管理
set方法内存管理
原则:如果在一个类中,有其它类的对象(关联关系),set方法中书写的时候,要判断是否是同一个对象,如果不是release掉旧值,retain新值。
二、@property
1. get,set方法实现办法:
1)@property + 手动实现
2)@property int age + @synthesize age
3)@property int age +@synthesize age = _age;
4)增强@property 生成get 和set :@property int age
2. 参数 格式:@property (参数1 ,参数2) 数据类型 方法名
![【OC语言】第六篇·内存管理 - 枫叶 - 枫叶的博客 【OC语言】第六篇·内存管理 - 枫叶 - 枫叶的博客](http://img2.ph.126.net/rlQjnt7AYcDDjKaKMQ6XQw==/6630293709514010921.png)
3. 循环retain解决办法
1)让某个对象先释放,另外一个对象多释放一次
2)推荐方法:一端使用assign 一端使用retain
三、@class
1. #import 作用:把要引用的头文件的内容,拷贝到#import处,如果引用的是#import “Person.h” 那么如果Person.h文件内容发生变化了,此时所有引用该头文件的类,需要重新编译。
2. @class 作用:可以简单的引用一个类(告诉编译器这是一个类,不会包含其内容)
3. @class使用
格式:@class 类名
好处:引用头文件内容发生改变,而不需要重新编译
4. 注意:
1).h 使用@class xx; .m 中使用#import "xx.h"
2)假如A类中#import “B.h” ,B类中#import "A.h" 形成循环引用导致错误。@class可以解决循环引用问题
四、自动释放池
1. 特殊栈结构
2. 特点:对象可以加入自动释放池中,自动释放池结束时,会给池中的每一个对象发送一条release消息
3. 使用:
@autoreleasepool { } //创建自动释放池
[对象 autorelease] //将对象加入自动释放池中
4. 好处:
不用再关心对象释
放的时间
不用再关心什么时候调用release
5.
autorelease的使用注意
占用内存较大的对象不要随便使用autorelease
占用内存较小的对象使用autorelease,没有太大影响