zoukankan      html  css  js  c++  java
  • iOS内存管理

    iOS内存管理的方式是引用计数机制。分为MRC(人式引用计数)ARC(自动引用计数)、

    为什么要学习内存管理?

    内存管理方式是引用计数机制,通过控制对象的引用计数来实现操作对象的功能。一个对象的生命周期有生成,持有,释放,销毁。引用计数分为ARC,MRC,在MRC中,增加引用计数的方法是retain,alloc,new,copy。减少引用计数的方法是release, autorelease,当引用计数增减平衡的时候,系统会自动执行对象的dealloc方法,销毁对象,完成该对象的内存管理。有创建就必须有释放。

     1.养成良好的内存管理习惯,可以从源头上避免内存问题的出现。

     2.一旦出现内存问题,能够找到并用解决。(调试bug

    引用计数管理内存的理念是:通过控制内存或者对象的引用计数来实现生成,持有,释放,销毁对象的操作。

     1.生成,对象的引用计数从01   - > 比如alloc

     2.持有,增加一个引用,让对象的引用计数加1   - >比如 retain

     3.释放,减少一个引用,让对象的引用计数减1   - > 比如 release  autorelease

     4.销毁,当对象的引用计数为0时,系统就会回收这个内存空间。  - > 比如 dealloc

     当这块空间被系统回收之后 ,就不能通过指针去访问这块空间了,容易造成野指针。

     切记!!引用计数这个概念,只存在于堆区区域,针对堆区的对象。

     生成,对应的方法是 + (instancetype)alloc; 在堆区域开辟一块内存空间,存放对象,并且将内存清零,同时将此对象的引用计数变为1,是从01的过程。

       //0 -> 1

        Person *person = [[Person alloc] init];

        //retainCount 这个方法可以查看对象的引用计数

        NSLog(@"person is %p, person's retainCount is %lu",person, [person retainCount]);

       

       //1

        Person *p1 = person;

        NSLog(@"p1 is %p, p1's retainCount is %lu", p1, [p1 retainCount]);

        //持有, 方法是 retain,让对象的方法加1

        //1 -> 2

        [person retain];

        NSLog(@"person is %p, person's retainCount is %lu",person, [person retainCount]);

        

        //2 -> 3

        [p1 retain];

        NSLog(@"p1 is %p, p1's retainCount is %lu", p1, [p1 retainCount]);

        

        //3 -> 4

        Person *p2 = [p1 retain];

        NSLog(@"p2 is %p, p2's retainCount is %lu", p2, [p2 retainCount]);

        

        //释放 release,让对象的引用计数减1 ,而且是立即减1

        [person release];

        NSLog(@"%lu",[person retainCount]);

        [person release];

        [person release];

        NSLog(@"%lu",[person retainCount]);

        [person release];//在执行这条release消息之前,对象person的引用计数为1release之后,引用计数为0,此时系统会自动试行dealloc方法,释放person对象,来完成person对象的内存管理。

        //下面这行代码可以打印出retainCount,为1,因为系统内部引用计数的值没有00只是方便交流引入的一个数,但从本质上来说, 这行代码已经有可能造成了野指针,因为person对象已经被系统回收,再去访问[person retainCount]就会出现问题。

        //野指针崩溃,是因为被回收的内存空间已经被占用了,再去访问会出现问题,不崩溃,只是侥幸,这块被回收的内存空间现在还没有被占用。

    autorelease 此方法也是让对象的引用计数减1,不过区别于releaseTA并不是立即减1,而是在未来的某个时刻,触发减1操作的这个时刻与自动释放池息息相关。

    自动释放池是一个容器,来记录池子内部对象接收到的autorelease消息,哪个对象接收,接收了几次,谁先接收,谁后接收,当池子释放时,autorelease消息真正执行减1操作。

    - (void)dealloc{

        NSLog(@"我的天,%@已经被释放了",self);

        [super dealloc]; 

    }只要重写了dealloc,[super dealloc]永远都在最后一行。先将自身的实例变量释放掉,然后再去执行父类中的dealloc方法,释放,继承过来的实例变量。dealloc方法释放的顺序,正好与初始化方法,初始化顺序相反。

  • 相关阅读:
    P5356 [Ynoi2017]由乃打扑克
    P4921 [MtOI2018]情侣?给我烧了!/P4931 [MtOI2018]情侣?给我烧了!(加强版)
    P2605 [ZJOI2010]基站选址
    CF1062E Company
    kd-tree
    扩展中国剩余定理(EXCRT)
    CF264C Choosing Balls
    CF1139D Steps to One
    P4655 [CEOI2017]Building Bridges
    P3311 [SDOI2014] 数数
  • 原文地址:https://www.cnblogs.com/xueyao/p/5188408.html
Copyright © 2011-2022 走看看