一. 内存管理的方式
1. 内存溢出
应用程序所加载的文件总和超过iOS系统分配的程序固定的RAM,引起的Crash,用户端体验则为闪退至桌面.
2. 野指针异常
对象的内存已被系统回收,但是仍然要通过指针来操作这块内存.引起Crash.
3. 内存的管理方式
a. 垃圾回收机制(Java开发一直使用) :程序员只需要开辟内存空间,不需要进行是否,由系统判断何时释放内存空间.
b. MRC:人工引用计数,内存开辟和释放空间由程序代码控制.相对垃圾回收机制来说,内存的回收相对灵活.对程序员的要求也很高,程序员要属性内存管理机制.
c. ARC:自动引用计数:iOS5.0后编译器的特性,至允许程序员开辟空间,不许程序员写释放空间的代码片段,简化开发成本.注:释放空间的代码有编译器自动添加.
d. iOS支持的两种内存管理方式:MRC与ARC.
e. MRC的内存管理机制为:引用计数
f. ARC是基于MRC的.
二. 引用计数机制,影响引用计数的各种方法
1. 引用计数机制
(前言)C语言中,无法记录多个指针指向同一内存地址的个数,只能通过指针进行开辟堆空间操作以及释放堆空间的操作.实际开发过程中,有多个指针指向同一内存单元.
a. OC中采用引用计数机制管理内存,每个对象都有一个引用计数器,用来记录当前对象的引用次数.原理:当一个新的引用指向对象时,引用计数器就+1,去掉一个引用时,引用计数器就-1,当引用计数器为0时,该对象的空间就会被系统回收释放.
b. retainCount返回的为该对象的引用值.(注意:自定义类实例化对象的引用值正常,若是系统类声明的对象,则可能返回的值不一定正常,或许系统其它框架的对象对其对象有所有权,则导致值与预期所想的不一致)
2. 影响引用计数的方法
a. 引用计数的步骤:
生成对象: +alloc
开辟内存空间,让被开辟内存空间的引用计数从0变至1
持有对象: -retain
调用一次该方法,该对象被持有一次所有权,则引用计数+1
释放对象: -release / -autorelease
release方法执行后,该对象的应用值立刻-1,-autorelease方法执行后,则在将来的某一时刻该对象的引用值-1,即对象调用autorelease方法后,对象则被添加到离autorelease方法最近的autoreleasepool(自动释放池)中,当自动释放池销毁时,为池中的每一个对象发送release方法.
销毁对象: -dealloc
b. copy 把某一对象的内容进行拷贝,原对象引用纸不变,新对象的引用值+1.
3. iOS5.0之前使用NSAutoReleasePool类创建对象,之后采用 @autoreleasepool{}代替,出了大括号,即自动释放池被回收,其中的对象同一被发送release消息.
4. dealloc方法为NSObject类的方法,即:当引用值为0的时候,销毁该对象使用的空间,重写dealloc方法,切记要[super dealloc],上方添加所需代码.
三. 内存管理的基本原则
1. 凡是使用了alloc,copy,contain的方法都是让内存引用增加了,所以都必须使用release与autorelease方法让内存引用减少,在一段代码片段内,增加和减少的次数要相等.
2. 如果增加的次数大于减少的次数,则会导致内存泄露.
3. 如果增加的次数小于减少的次数,会导致过度释放.
4. 如果增加的次数等于减少的次数,但还能继续访问,会造成野指针问题.
四. 协议(类似Java中的接口)
1. Protocol(为一堆方法的声明),即只有.h文件,类似于一张任务清单,清单交给谁,谁就要完成该清单上的方法.
2. 接受协议的类实现协议中的方法.
3. 协议中@required修饰的方法,在类中必须实现,@optional的方法,在类中可选择性的实现.
4. 类遵守协议即在类的声明部分父类后边使用"<Protocol>"使用遵循多个协议时即:<Protocol1,Protocol2,....>
5. 协议的优点:让接受协议的类间接扩展了实例方法,因为一个类可以同时遵守n个协议,所以可以解决OC中类无法多继承的问题.
五. 内存拷贝
1. 一个对象要想进行拷贝必须服从NSCopying协议,定义copy的方法,如果类没有接受NSCopying协议发送copy消息,则会发生Crash.
2. NSCopying协议中为定义- (id)copyWithZone:(NSZone *)zone;方法,该方法分为三种类型.
a. 伪拷贝
伪拷贝相当于进行了retain的操作,使得该内存空间的引用数+1
- (id)copyWithZone:(NSZone *)zone {
return [self retain];
}
b. 浅拷贝
浅拷贝则为内存中出现了两个一模一样的对象,但是两个对象的实例变量指向的是同一空间.
c. 深拷贝
深拷贝则为内存中出现了两个一模一样的对象,两个对象的实例变量指向不同的空间.
3. mutableCopy方法返回的结果是一个一模一样的对象,在内存中的不同的单元.即clone出来的对象.