OC第九天:内存管理初级

⼀、内存管理的⽅式。
为什么要使⽤内存管理
在⼀个拥有数⼗个甚⾄是上百个类的⼯程⾥,查找内存问题极其困 难。了解内存常⻅问题,能帮我们减少出错⼏率。
内存问题体现在两个⽅⾯:内存溢出、野指针异常。
内存溢出
iOS给每个应⽤程序提供了⼀定的内存,⽤于程序的运⾏。⼀旦超出内存上限,程序就会Crash。
野指针异常
对象内存空间已经被系统回收,仍然使⽤指针操作这块内存。野指 针异常是程序crash的主要原因。代码量越⼤的程序,越难找出出现 野指针的位置。
了解内存管理,能帮我们提升程序性能,⼤⼤减少调试bug时间。
内存管理的⽅式
垃圾回收(gc)
MRC(Manual Reference Count)
ARC(Auto Reference Count)
内存管理的⽅式
垃圾回收:程序员只需要开辟内存空间,不需要⽤代码显⽰地释 放,系统来判断哪些空间不再被使⽤,并回收这些内存空间,以便再 次分配。整个回收的过程不需要写任何代码,由系统⾃动完成垃圾回 收。Java开发中⼀直使⽤的就是垃圾回收技术。
Manual Reference Count,⼈⼯引⽤计数:内存的开辟和释放都由 程序代码进⾏控制。相对垃圾回收来说,对内存的控制更加灵活,可 以在需要释放的时候及时释放,对程序员的要求较⾼,程序员要熟悉 内存管理的机制。
Auto Reference Count,⾃动引⽤计数:iOS 5.0的编译器特性,它 允许⽤户只开辟空间,不⽤去释放空间。它不是垃圾回收!它的本质 还是MRC,只是编译器帮程序员默认加了释放的代码。
iOS的内存管理
iOS⽀持两种内存管理⽅式:ARC和MRC。
MRC的内存管理机制是:引⽤计数。
ARC是基于MRC的。

⼆、引⽤计数机制,影响计数的各个⽅法。
引⽤计数
C语⾔中,使⽤malloc和free,进⾏堆内存的创建和释放。堆内存只 有正在使⽤和销毁两种状态。
实际开发中,可能会遇到,两个以上的指针使⽤同⼀块内存。C语⾔ ⽆法记录内存使⽤者的个数。
OC采⽤引⽤计数机制管理内存,当⼀个新的引⽤指向对象时,引⽤ 计数器就递增,当去掉⼀个引⽤时,引⽤计数就递减。当引⽤计数到 零时,该对象就将释放占有的资源。
影响引⽤计数的⽅法
+alloc
+alloc:开辟内存空间,让被开辟的内存空间的引⽤计数变为1。 这是由0到1的过程。
-retain
-retain:引⽤计数加1,如果内存空间之前引⽤计数为1,ratain之 后变为2,如果引⽤计数是5,retain之后变为6。
-copy
-copy:把某⼀内存区域的内容拷⻉⼀份,拷⻉到新的内存空间⾥ 去,被拷⻉区域的引⽤计数不变,新的内存区域的引⽤计数为1。
-release
-release:引⽤计数减1,如果内存空间之前引⽤计数为4,release 之后变为3,如果之前引⽤计数为1,release之后变为0,内存被系 统回收。
-autorelease
-autorelease:未来的某⼀时刻引⽤计数减1。如果内存之前引⽤计 数为4,autorelease之后仍然为4,未来某个时刻会变为3。



autoreleasepool的使⽤

通过autoreleasepool控制autorelease对象的释放。 向⼀个对象发送autorelease消息,这个对象何时释放,取决于 autoreleasepool。
NSAutoreleasePool *pool= [[NSAutoreleasePool alloc]init];和 [pool release];就像⼀对括号,[xxx autorelease];必须写在两者之 间。

[xxx autorelease];出现在了两者之间,pool就会把接收 autorelease的对象给保存起来(以栈的⽅式,把对象压⼊栈)

当[pool release];的时候,pool会向之前保存的对象逐⼀发送 release消息(对象出栈,越晚autorelease的对象,越早接收 release消息)。


在iOS5之后,不再推荐使⽤NSAutoreleasePool类,使⽤ @autoreleasepool{}替代。
之前写在NSAutoreleasePool *pool= [[NSAutoreleasePool alloc]init];和[pool release];之间的代码,需要写在 @autoreleasepool{}的⼤括号⾥。
出了⼤括号,⾃动释放池才向各个对象发送release消息。


三、dealloc⽅法
-dealloc是继承⾃⽗类的⽅法,当对象引⽤计数为0的时候,由对 象⾃动调⽤。
我们可以在dealloc中打印⼀句话,验证对象引⽤计数是否降为0.
- (void)dealloc{ NSLog(@“%@被销毁了”,self); [super dealloc]; }


四、内存管理的基本原则。
引⽤计数的增加和减少相等,当引⽤计数降为0之后,不应该再使 ⽤这块内存空间。
凡是使⽤了alloc、retain或者copy让内存的引⽤计数增加了,就需 要使⽤release或者autorelease让内存的引⽤计数减少。在⼀段代码 内,增加和减少的次数要相等。

五、掌握copy的实现。
-跟retain不同,⼀个对象想要copy,⽣成⾃⼰的副本,需要实现 NSCopying协议,定义copy的细节(如何copy)。如果类没有接 受NSCopying协议⽽给对象发送copy消息,会引起crash。
// 类方法 便利构造器方法使用 autorelease
// 其他方法 需要在外部释放这是规范
// 在实例拷贝方法对计数多大影响
   //伪拷贝
    // 浅拷贝
   
// 拷贝后两个对象 但是赋值是相同的指向同一地址
     // 深拷贝 拷贝新对象 赋值也是新的
   
// 对字符串进行拷贝拷贝结果看字符串这个类如何实现拷贝方法 对不可变字符串的拷贝其实相当于 直接 retain 一次
   // 可变字符串拷贝时就是真拷贝了一个新的出来


总结

OC借助引⽤计数机制去管理内存,凡是使⽤了alloc、copy、retain等⽅ 法,增加了引⽤计数,就要使⽤release和autorelease减少引⽤计数,引⽤ 计数为0的时候,对象所占的内存,被系统回收。
autorelease是未来某个时间(出autoreleasepool)引⽤减⼀,不是即时 的。
不是任何对象都可以接收copy消息,只有接受了NSCopying协议的对象 才能接收copy消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值