理解__unsafe_unretained

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/junjun150013652/article/details/53148711

概述

这里假设你已经熟悉__strong和__weak,如果不懂就不用继续往下看了。

__unsafe_unretained:__weak 一样,唯一的区别便是,对象即使被销毁,指针也不会自动置空, 此时指针指向的是一个无用的野地址。如果使用此指针,程序会抛出 BAD_ACCESS 的异常。 

举例分析:

下面我们通过两个简单的例子来分析一下,以下如果未特别说明,都是在ARC环境下:

我们先来看第一个例子:

    id __unsafe_unretained obj = [[NSMutableArray alloc]init];
    [obj addObject:@"obj"];

这里先不管编译器的警告,继续执行,在第二条语句就会崩溃,分析:

附有__unsafe_unretained修饰符的变量同附有__weak修饰符的变量一样,因为自己生成并持有的对象不能继续为自己持有,所以生成的对象会立即被释放。也就是说在执行完init方法以后,obj指针所指向的内存就已经释放掉了,可是obj指针并没有像附加__weak的指针那样,将指针自动置为nil,它依然指向原来的地址,可是这块地址的内存已经被系统回收了,再访问就是非法的,也就是野指针,再执行后面的addObject方法自然会出错了。

也就是说上面的代码,把__unsafe_unretained换成__weak就不会崩溃,因为obj会自动制置为nil。对nil发送消息是不会有问题的。


这里我们再通过一个例子分析一下:

    id __unsafe_unretained obj1 = nil;
    {
        id  obj0 = [[NSMutableArray alloc]init];
        [obj0 addObject:@"obj"];
        obj1 = obj0;
        NSLog(@"obj0 = %@", obj0);
    }
    
    NSLog(@"obj1 = %@", obj1);

依然在最后的NSLog语句崩溃。分析:

因为__unsafe_unretained既不强引用,也不弱引用,作用域外obj0强引用失效,并且没有其他指针强引用这个对象,所以自动释放持有的对象,obj1就相当于野指针,访问野指针就会崩溃;

也就是说,赋值给附有__unsafe_unretained修饰符变量的对象在通过该变量使用时,如果没有确保其确实存在,那么应用程序就会崩溃;




展开阅读全文

没有更多推荐了,返回首页