[objective-C] 08.内存管理1

了解内存管理的方式:
  1. 为什么要使用内存管理?
    随着Retina屏幕的出现,程序对素材的要求也有所提高,素材的像素能力需要是非Retina屏素材像素的4倍,无疑会对内存造成一定压力,更容易达到内存上限,除了内存溢出造成crash之外,程序里的野指针也是造成App crash的主要原因。程序开发中,程序crash多数是由于内存问题导致的,因此掌握内存管理是分许元必备的技能。
  2. 内存管理的方式:
    垃圾回收(gc)
    ARC(Auto Reference Count)
    MRC(Manual Reference Count)
  3. 垃圾回收:
    程序只需要开辟内存空间,不需要用代码显示地释放,系统来判断哪些空间不再被使用,并回收这些内存空间,以便再次分配。整个回收的过程不需要写任何代码,由系统自动完成垃圾回收。Java开发中一直使用的就是垃圾回收技术。
  4. ARC:
    Auto Reference Count,自动引用技术:iOS5.0的编译器特性,它允许用户只开辟空间,不去释放空间。它不是垃圾回收!它的本质还是MRC,只是编译器帮程序员默认加了释放的代码。
  5. iOS支持两种内存管理方式:ARC和MRC
  6. MRC的内存管理机制是:引用计数


掌握内存管理各个关键字的作用:
  1. 在引用计数中,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递增。当引用计数到零时,该对象就将释放占有的资源。
  2. 影响引用计数的方法:
    +alloc
    -retain
    -copy
    -release
    -autorelease
  3. +alloc:开辟内存空间,让被开辟的内存空间引用计数变为1。这是由0到1的过程
  4. -retain:引用计数加1,如果内存空间之前引用技术为1,retain之后变为2,如果引用计数是5,retain之后变为6.
  5. -copy:把某一内存区域的内容拷贝一份,拷贝到新的内存空间里去,被拷贝区域的引用计数不变,新的内存区域的引用技术为1.
  6. -release:引用技术减1,如果内存空间之前引用技术为4,releaes之后变为3,如果之前引用技术为1,release之后变为0,内存被统一回收。
  7. -autorelease:未来的某一时刻引用技术减1。如果内存之前引用计数为4,autorelease之后仍然为4,未来某个时刻会变成3。
  8. copy方法:
    跟retain不同,一个对象想要copy,生成自己的副本,需要实现NSCopying协议,定义copy的细节(如何copy)。如果类没有接受NSCopying而给对象发送copy消息,会引起crash。
  9. copy方法的实现:

    - (id)copyWithZone:(NSZone *)zone

    {

        Person *person = [[Person allocWithZone:zone] init];

        person.name = self.name;

        person.age = self.age;

        return person;

    }



掌握内存管理的基本原则:
  1. 引用计数的增加和减少相等,当引用技术降为0之后,不应该再使用这块内存空间
  2. 凡是使用了alloc、retain或者copy让内存的引用技术增加了,就需要使用release或者autorelease让内存的引用技术减少。在一段代码内,增加和减少的次数要相当。
  3. autoreleasepool的使用
    通过autoreleasepool控制autorelease对象的释放。
    向一个对象发送autorelease消息,这个对象何时释放,取决于autoreleasepool

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


    Person *p = [[Person alloc] init]; // retainCount1

    [p retain]; // retainCount2

    [p autorelease]; // retainCount未来的某个时刻释放


    [pool release];


    NSLog(@"%lu", (unsigned long)[p retainCount]);

  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];和[pool release];就像一个一对括号,[xxx autorelease];必须写在两者之间。
  5. [xxx autorelease];出现在两者之间,pool就会把接收autorelease的对象保存起来(以栈的方式,把对象亚入栈)
  6. 当[pool release];的时候,pool会向之前保存的对象逐一发送release消息(对象出栈,越晚autorelease的对象,越早接收release消息)
  7. 在iOS5之后,不在推荐使用NSAutoreleasePool类,使用@autoreleasepool{}替代,之前写在NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];和[pool release]; 之间的代码,需要写在@autoreleasepool{}的大括号里。出现大括号,自动释放池才向各个对象发送release消息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值