iOS内存管理基础0

作者: 王大吉Rock | 来源:发表于2019-01-06 23:55 被阅读2次

    一个oc对象的引用计数时机

    最近冥想一个这样的问题:我们都知道ARC机制是一种简单有效地管理oc对象生命周期的方式,当一个实例被创建的时候,实例的引用计数会变成1,当一个新的指针指向实例的时候,它的引用计数会变成2,当没有指针指向这个实例的时候它的引用计数会变成0,这个时候ARC机制会销毁该实例并回收内存...
    那么一个继承于NSObject类的实例,其引用计数是什么时候第一次被+1的呢,是alloc的时候,还是init的时候,还是时候呢?

    这是一个非常基础的问题,我们分为下面三种情况分析下

    情况1:

    其实我们知道新实例被创建后,只要被强引用了,其引用计数必然会+1,那么在一个函数中如果我们只创建了一个实例:

    - (void)test {
        [[NSObject alloc] init];
    }
    

    此实例的引用计数是怎么样的呢?
    我们知道alloc的时候实例的内存被分配,init的时候实例内部的属性等会被创建,但是其没有被任何对象或者属性引用,可以认为是没有被指针指向的,所以此时实例的引用计数为0,当执行完test函数后,实例会被销毁。

    情况2:

    - (void)test {
        NSObject *obj = [[NSObject alloc] init];
        NSLog(@"引用计数:%lu", (unsigned long)[obj retainCount]);
    }
    

    那如果是这样,其实例的引用计数会是多少呢?
    答案是:引用计数:1,因为实例被创建后,被obj变量的指针所指向了,也就是说objc变量持有了该实例,所以打印的结果会是1。同样的,当执行完test函数后,实例会被销毁。

    情况3:

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property(nonatomic, strong) NSObject *obj;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self test];
        NSLog(@"引用计数:%lu", (unsigned long)[self.obj retainCount]);
    }
    
    - (void)test {
        NSObject *obj = [[NSObject alloc] init];
        NSLog(@"引用计数:%lu", (unsigned long)[obj retainCount]);
        self.obj = obj;
        NSLog(@"引用计数:%lu", (unsigned long)[obj retainCount]);
    }
    @end
    

    此时两次的log是如何呢?
    答案是:引用计数:1引用计数:2引用计数:2[[NSObject alloc] init]实例创建后被objself. obj两个变量的指针指向了...函数结束后,因为ViewController持有self. objself. obj持有着实例,所以其引用计数不会为0

    引用计数和方法作用域

    在上述情况2中最终[[NSObject alloc] init]实例会被销毁呢?
    答案是和函数的作用域有关系的,函数中的局部变量是在中,比如情况2中的obj变量,其本质就是一个指针,在函数结束的时候,系统就会释放这个指针。所以函数结束时,就没有指针指向实例,其引用计数为0,在ARC的环境下就会自动销毁该实例。

    如果你想了解iOS的内存存储区域、循环引用&解决循环引用的本质,可以转到iOS内存管理基础1

    相关文章

      网友评论

        本文标题:iOS内存管理基础0

        本文链接:https://www.haomeiwen.com/subject/gymerqtx.html