探讨声明UI控件属性 什么时候用weak什么时候用strong

版权声明:欢迎大家积极分享!交流。关注我~ https://blog.csdn.net/qinqi376990311/article/details/52934040

也许我们在学习的时候,有人会告诉我们,UI控件的属性用weak修饰,而且,从Storyboard中拖出来的控件也都是用weak来修饰的,所以在习惯上,我们总会用weak去修饰。然而,在某些情况下,这么做是会出问题的,这时我们必须用strong来修饰。

探讨之前,首先要了解Objective C的内存管理机制,即引用计数。
一个对象何时会被释放呢?答案是,当引用计数为0的时候。

建立一个UIView,声明一个控件属性,用weak修饰

@property (nonatomic, weak) UIView *aView;

那么我们将分两种情况来进行测试。

一、在viewDidLoad中初始化这个控件。

初始化

可以看到编译器已经给出警告了,当这行代码执行完,这个UIView就会被释放掉了。
接下来我们换一种写法

初始化一个View并赋值给属性

此时编译器已经不会报错了,但是这么写是有问题的,当出了最下面这个大括号之后,这个对象也将不复存在。也会变成nil.

添加到子视图

或者懒加载

懒加载

诶,我们平时就是这么写的。那么为什么这么写这个视图就不会消失了呢?而且在别的方法中再访问self.aView也是有值的呢。
我们进到系统的UIView.h头文件中,可以看到这个属性。当我们执行了addSubview:方法之后,后面的视图就会被放到这个数组里。

UIView头文件

可以看到,这个数组使用copy修饰的,也就是说,这是强引用!正是这个原因,我们才能用weak来修饰一个控件。因此可以保持这个控件的引用计数不为0,就不会被释放掉了。

那么我们在开发中,到底是用weak还是用strong?

1、如果你真的怕麻烦,也不想理解什么内存管理,你就用strong就对了。
2、可以分情况来看,如果你用strong修饰了属性,并且也addSubview:了,虽然引用计数为2,但是当整个父视图被销毁的时候,这两个引用计数都会变成0,所以不会造成内存泄漏。
3、具体的情况就是,我们有时候在一个视图1中,需求要求我们声明一个视图2,这个视图2不一定是视图1的子视图,此时假如视图2有值:那么weak时,引用计数为0,这个视图相当于不存在。strong时,引用计数为1,不管你添加不添加到视图1的子视图,视图2都存在。简要概括:

视图2有值的情况下,如何保证它不会消失?其实就是保证它不被释放。
weak:视图1存在,视图2不一定存在。取决于视图2是否有强引用。
strong:视图1存在,视图2就存在。因为strong会使引用计数+1.

可以参考另一篇文章:探讨OC的内存管理

猜你喜欢

转载自blog.csdn.net/qinqi376990311/article/details/52934040
今日推荐