当前位置: 首页 > news >正文

【转】self.myOutlet=nil、viewDidUnload、dealloc的本质剖析

对于iphone开发人员来说,内存管理是极为重要的技巧,哪怕程序的功能再强大,设计再漂亮,如果内存控制不好,也难逃程序莫名退出的噩运,这与网页开发是完全不同的。

内存控制里面有很多门道,在这里分析一下 viewDidUnload 和 dealloc 的区别,关于这两者的区别的文章很多,但是大都是摘抄和翻译官方文档,有的也只是简单的说两句,并没有详细说出两者具体的区别。

在了解两者之间的区别,首先要知道 view 的生命周期,google 里面有很多文章,可以先去搜一下,这里就不详解了。

顾名思义  viewDidUnload 就是当 view 被卸载以后执行的语句,它与 viewDidLoad 是相互呼应的。大家都知道官方的解释是执行类似

 

self.myOutlet = nil;

 

的命令,但是为什么这么干,什么时候调用这个方法呢?

这个方法是不能手动调用的,它实际上是当应用程序接收到手机内存警告的时候自动调用的方法,目的就是清空内存除当前 viewController 以外所有已经加载过的 viewController 里面的暂时不再使用的一些控件或数据,以避免应用程序应消耗内存过多被强制关闭。记住,是除当前正在展示的 view 所属 viewController 以外所有已经在内存里面的 viewController 执行 viewDidUnload 方法,而不是当前 viewController 执行 viewDidUnload,当然,这些 viewController 不会被 dealloc。所以在 viewDidUnload 里面一般都是释放 IBOutlet 变量和在 viewDidLoad、viewWillAppear、viewDidAppear 等方法能够重建的数据。而由其他页面传递过来的数据或者无法经过 viewDidLoad、viewWillAppear、viewDidAppear 等方法重建的数据则不能释放,举例子说如果在 navigationController 由上一个页面传递过来的一张图片,在 viewDidUnload 里被释放的话,则当 view 再次加载的时候就无法恢复了。

/*************************重要************************/
那为什么要写成 self.myOutlet = nil; ,实际上这个语法是执行了 property 里的setter 方法,而不是一个简单的变量赋值,它干了两件事:1、老数据 release 掉,2、新数据(nil)retain(当 property 设置为 retain 的情况下),当然对 nil retain 是无意义的。如果写成 myOutlet = nil,那就是简单的把 myOutlet 指向 nil,这样内存就泄漏了,因为老数据没有 release。而如果仅仅写成 [myOutlet release] 也会有问题,因为当 view 被 dealloc 的时候会 再次 release,程序就出错了,而对 nil release 是没有问题的。  这样就不必担心,viewDidUnload释放后,dealloc又重复释放而崩溃的情况出现了。
 
dealloc 是当前 viewController 被释放的时候,清空所有当前 viewController 里面的实体和数据来释放内存,该方法也是自动调用的,无需手动执行。举例说明当 modalView 被 dismissModalViewControllerAnimated 或者 navigationController 回到上一页的时候,这个方法就会被自动调用。因为这个页面已经不再使用了,所以可以把所有实体和数据都释放(release)掉。

其实两者最大的区别就是: viewDidUnload 是内存除当前以外所有 viewController 同时执行,而 dealloc 只是当前 viewController 执行。这个是网上的材料没有说明的。

个人拙见,不对之处还请提正!

PS: 很多朋友都说无法调试 viewDidUnload,其实是可以的。方法是在 iOS 模拟器的菜单里选 硬件 -> 模拟内存警告,这个时候就可以看到 viewDidUnload 里面 NSLog 的东西了,可以试试在打开过的 viewController 里都 NSLog 一下看看效果。而 dealloc 里面可以直接 NSLog。

本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/p/3386284.html,如需转载请自行联系原作者

相关文章:

  • Find Blank Cell in Excel
  • 浮动元素引起的问题和解决办法?
  • 使用 pod install 还是 pod update ?
  • SylixOS中APIC HPET定时器字符驱动实现
  • 如何在windows上调试安卓机谷歌浏览器上的页面
  • django-权限管理
  • [转]OOA/OOD/OOP区别
  • 绝对常用的Linux命令
  • 【HeadFirst 设计模式学习笔记】3 装饰模式
  • Windows Phone 7 学习笔记2:感应设备的方向
  • ssh 断开处理
  • 关于JavaScript 的事件[下]
  • table-layout
  • 双系统引导故障排除
  • python 守护进程(daemon)
  • 分享一款快速APP功能测试工具
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【刷算法】求1+2+3+...+n
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • android 一些 utils
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • React16时代,该用什么姿势写 React ?
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • tab.js分享及浏览器兼容性问题汇总
  • 初识MongoDB分片
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 基于webpack 的 vue 多页架构
  • 数据科学 第 3 章 11 字符串处理
  • 思考 CSS 架构
  • 项目管理碎碎念系列之一:干系人管理
  • MyCAT水平分库
  • 我们雇佣了一只大猴子...
  • ​iOS安全加固方法及实现
  • %check_box% in rails :coditions={:has_many , :through}
  • (C++)八皇后问题
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (十六)串口UART
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)memcache、redis缓存
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转载)hibernate缓存
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .describe() python_Python-Win32com-Excel
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .net 生成二级域名
  • .NET 依赖注入和配置系统
  • .net经典笔试题
  • .NET中统一的存储过程调用方法(收藏)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @RequestBody与@ResponseBody的使用
  • @Responsebody与@RequestBody
  • @RestControllerAdvice异常统一处理类失效原因