内存管理



【内存管理】
    内存管理就是确保申请的内存能够得到合理及时的释放
    1、忘记释放一个堆空间,称为【内存泄漏】
    2、使用已经释放的内存,称为【提前释放】
    3、多次释放同一堆空间,称为【重复释放】

【困境】
    1、释放一个堆空间,需要确保所有指向该空间的指针都不再使用
    2、释放一个堆空间,需要确保指向同一空间的指针只释放一次
    3、模块化操作时,哪个模块负责释放将成为巨大的难题
    4、多线程操作时,没有办法确定哪个线程最后结束
【解决】
    采用类似于聊天室的计数方式。第一个人开始聊天时创建聊天室,并将计数值设置为1。当多一个人加入聊天室时,将计数值加1;当一个人离开聊天室时,将计数值减1,计数值减到0时释放聊天室。
    其实就是确保聊天室中的人数与计数值相等。
【结论】
    在创建对象时将其引用计数设置为1,当多一个指针指向该对象时将计数值加1;当少一个指针指向对象时将计数值减1,计数值减到0时释放对象。
    其实就是确保指向对象的指针数等于计数值
一、手动内存管理
  Manual Reference Counting,简称MRC
【关闭ARC】
    1、工程 —> gar
    2、Yes —> No
【相关方法】
   1、获取对象的引用计数
        NSUInteger count = [dog retainCount];

   2、使对象的引用计数加1
    //将对象的引用计数加1,并返回该对象的地址
    //平白无故的retain是不允许
    JYDog *dog2 = [dog retain];

   3、使对象的引用计数减1,减到0时释放对象
    [dog2 release];

   4、析构方法
        //析构方法,在对象释放时自动调用
    - (void)dealloc
    {
        NSLog(@"dog 对象即将释放");
        [super dealloc];
    }

【黄金法则】
    1、凡是用alloc/new/retain/copy(开头)/mutableCopy(开头)等创建的对象,
都需要调用release/autorelease进行释放。
    2、谁写alloc,谁写release;哪个类创建,哪个类释放

【注意事项】
    1、对象的子对象需要在析构方法中释放
    2、在指针转移时,应先释放就对象,然后指向新对象
    3、数组的内存管理,见【数组的内存管理】demo
    4、[[JYClass alloc] init] <==> [JYClass new]
    5、(mutable)copy基本上只有在NSString上
      6、字符串类型的内存计数器为-1
【自动释放】
    以前不是关键字,是一个类NSAutoreleasePool,可以将需要释放的对象存放在其中(类似于一个数组),等池释放时将其中的对象各释放一次,也叫延迟释放。
    现在为了配合ARC改成关键字@autoreleasepool
 【说明】
    1、一定要结合自动释放池
    2、对象的引用计数不会直接减1,等池释放时才会减1
 【自动释放原则】—— 非用不可的时候
    1、类方法创建的对象
    2、getter方法中[[_name retain] autorelease]
二、自动内存管理(后面阶段)
    Automatic Reference Counting,简称ARC
    1、将MRC的文件转换为ARC的
    2、MRC和ARC共存(混编)
【copy】
NSString *str1 = @"123456";
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
//copy和mutableCopy拷贝出来的对象与原对象无关
//copy拷贝的对象都是不可修改的
  //mutableCopy拷贝的对象都是可以修改的

原文地址:https://www.cnblogs.com/rainwz/p/4589057.html