深入详解 IOS strong 和 weak

深入详解  IOS strong  和 weak

 

今天写点深刻的关于内存管理的东西

 

IOS  采用arc  管理内存    让程序员不在纠结于内存的开辟释放等繁琐的工作

 

让内存管理更加简单 

 

arc  是类似于垃圾回收机制  当一个对象没有一个强引用 指向它的时候  该 对象就会被自动释放

当一个对象被引用一次  就会给计数器加1   当对象的计数器变为0的时候就会被arc机制 回收

所以 记住一个原则   :   至少有一个强引用指向的对象才不会被销毁

 

科普一下    引用  有两种   strong (强引用) 和weak(弱引用)

 

下面通过一个非常深刻的问题来解释 strong和  weak的   使用

 

1.为什了控件的属性可以用strong  也可以用weak  对使用效果没有影响 而 代理必须用weak?

 

首先看   控件属性   假设  有一个 按钮(UIButton)  被添加到了 控制器的View上

那么相当于 :

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];

    [self.view addSubview:btn];

self.view  有一个 子控件数组    self.view.subviews

是一个数组 NSArray *subviews

这个时候  就有一个  强引用 在数组中  指向我们的按钮  btn

 

而控制器  这个时候还可以通过连线 或者直接添加属性的方式对按钮进行引用   

@property (nonatomic , weak)UIButton *btn;

 

如果是控制器的属性是weak   按钮就有一个弱指针(控制器的属性) 和一个强指针(self.view的数组)指向它    只要有一个强引用指向它  对象就不会被销毁  所以 这个时候  按钮是存在的

知道 控制器的View   被销毁  View的数组也会被销毁  按钮的强引用就不在了   这个时候按钮只有一个控制器的weak属性来指向它  所以也会被销毁

 

如果是控制器的属性是strong  按钮就有两个强引用  指向它

 

等控制器的View 销毁的时候  按钮还不会被销毁 因为控制器的属性还引用着    会不会出现野指针的问题呢?

当然不会   因为 控制器的销毁和view的销毁 是一致的 view

View都不在的时候   控制器也已经不在了

 

所以  控制器  中  连线 或者   设置  控件的属性的时候   可以用 stong  也 可以用   weak

 

接下来 看   在代理中 为什么  只能用weak 而不能用strong

 

以UITableView 为例  它有两个属性

@property (nonatomic, assign)   id <UITableViewDataSource> dataSource;

@property (nonatomic, assign)   id <UITableViewDelegate>   delegate;

都是weak 

 

UITableView   会在  UITableViewController控制器中

 

那么控制器有一个强引用 指向UITableView

 

谁来充当 UITableView的代理和数据源呢   ?

我们都知道一般都是控制器来充当

那么  UITableView 就有两个属性 引用着控制器

若果 这两个属性都是  强引用   那么控制器在UITableView释放之前就不会被释放 因为UITableView在  代理和数据源属性就在  控制器就在

而UITableView被控制器强引用着   控制器在  UITableView就在  这样至少要有一个 对象被释放另一个才能被释放

 

他们互相引用着对方  所以知道程序结束 控制器销毁 UITableView  才能被销毁  控件的生命周期和整个应用程序一样了 这是很可怕的

 

深究一下   其实控制器 不需要 UITableView来强引用

 

因为控制器会被添加到 它的父控制器的子控制器数组中   或者

被添加到根视图控制器中  所以 控制器的生命周期和它的父控制器是绑定的(由父控制器来决定当前控制器的死活)    一层一层的上溯  直到UIWindow *window  的

window.rootViewController 又直到AppDelegate

 

所以  代理设置成weak  就能避免这种相互包含的情况

 

 父控制器  有权结束当前控制器  把当前控制器干掉了

 

UITableView的代理和数据源是weak  所以控制器会被销毁

 

那么 UITableView也就失去了强引用 随即被销毁

 

总结一句  :  代理必须用weak     控件  可以strong 可以weak

 

 

其实  不用去死记      一个对象是不是该存在  都能找到最应该决定它生命周期的那个对象  

 

 

实线是强引用   虚线 是弱引用

 

 

欢迎探讨任何IOS开发的问题 请注明来自博客园    QQ:137569752      莫妄莫念

 

 

 

 

 

posted on 2013-12-28 20:06  莫妄莫念  阅读(945)  评论(0编辑  收藏  举报