322,__unsafe_unretained 的理解和使用(面试点:__unsafe_unretained和__weak一样,表示的是对象的一种弱引用关系,唯一的区别是:__weak修饰的对象...

如果你懂得__weak 和 __strong修饰词的含义,那么你可以继续看下去。
__unsafe_unretained和__weak一样,表示的是对象的一种弱引用关系,唯一的区别是:__weak修饰的对象被释放后,指向对象的指针会置空,也就是指向nil,不会产生野指针;而__unsafe_unretained修饰的对象被释放后,指针不会置空,而是变成一个野指针,那么此时如果访问这个对象的话,程序就会Crash,抛出BAD_ACCESS的异常。

那么这时候通常就会有疑问,那为什么有__weak还要用__unsafe_unretained呢?

1.__weak只支持iOS 5.0和OS X Mountain Lion作为部署版本(当然对于现在,这个原因已经可以无视了)

2.__weak对性能会有一定的消耗,使用__weak,需要检查对象是否被释放,在追踪是否被释放的时候当然需要追踪一些信息,那么此时__unsafe_unretained比__weak快,而且一个对象有大量的__weak引用对象的时候,当对象被废弃,那么此时就要遍历weak表,把表里所有的指针置空,消耗cpu资源。

那么什么时候使用__unsafe_unretained呢?

当你明确对象的生命周期的时候,可以使用__unsafe_unretained替代__weak,可以稍微提高一些性能,虽然这点性能微乎其微。

举个例子,当A拥有B对象,A消亡B也消亡,这样当B存在,A也一定会存在的时候,此时B要调用A的接口,就可以通过__unsafe_unretained 保持对A的引用关系。

比如 MyViewController 拥有 MyView, MyView 需要调用 MyViewController 的接口。MyView 中就可以通过 __unsafe_unretained 保持对MyViewController的引用。

__unsafe_unretained MyViewController * myVC;

我们可以通过代码来看下__weak和__unsafe_retained使用的区别。

image.png
image.png

通过图1和图2的对比,可以很明显的发现,使用__weak修饰的obj对象在被释放后,指向对象的指针被置空了,而使用__unsafe_unretained修饰的obj对象在被释放后,指向对象的指针成为野指针了,当访问对象addObject方法的时候,抛出异常。

你可能感兴趣的:(322,__unsafe_unretained 的理解和使用(面试点:__unsafe_unretained和__weak一样,表示的是对象的一种弱引用关系,唯一的区别是:__weak修饰的对象...)