惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
The GitHub Blog
The GitHub Blog
C
Check Point Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
F
Full Disclosure
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
G
GRAHAM CLULEY
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
C
Cybersecurity and Infrastructure Security Agency CISA
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
博客园 - 司徒正美
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
云风的 BLOG
云风的 BLOG
Cisco Talos Blog
Cisco Talos Blog
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
V
V2EX - 技术
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Spread Privacy
Spread Privacy
罗磊的独立博客
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security Affairs
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
O
OpenAI News
Jina AI
Jina AI
PCI Perspectives
PCI Perspectives
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
I
InfoQ
D
Docker
P
Palo Alto Networks Blog
Recorded Future
Recorded Future
M
MIT News - Artificial intelligence
博客园 - Franky
B
Blog
Scott Helme
Scott Helme
博客园 - 叶小钗
D
DataBreaches.Net

博客园 - 啊夏

ios平台上一个由字节对齐问题导致的crash NSURLConnection 网络超时的那些事。 我看QQ与360的恩怨情仇 [转载]NSString+NSMutableString+NSValue+NSAraay用法汇总 详解百度手机输入法“搜索框”的秘密 一道求单向链表倒数第N个结点的算法题。 真正认识 realloc 的工作方式。 什么是最优秀的IT员工? 【转帖】有关次级贷的一个故事。很贴切 获取字符串的拼音首字母 [转载]关于const用法的 笔记记录 最大公约数-辗转相除法 向量的旋转算法---编程珠玑读书笔记。 activex 控件回调 javascript 一个“利”与“义”的故事。 重启PPC系统 GLDEF_C, LOCAL_C, GLREF_C 的含义 看看80的我们小时候都在玩些什么。 Carbide.c++ IDE的常用快捷键和技巧
iOS6.0以后App对内存警告的处理
啊夏 · 2013-01-11 · via 博客园 - 啊夏

   今天在调试代码的时候,用模拟器模拟内存警告,结果发现自己的ViewController竟然不响应viewDidUnload函数,尼玛,这可是个大问题。

   查询文档,iOS升级到6.0以后,不再支持viewDidUnload了。官方文档的解释是系统会自动控制大的View所占用的内存,其他小的View所占用的内存是极其微小的,不值得为了省内存而去清理然后在重新创建。如果你需要在内存警告的时候释放业务数据或者做些其他的特定处理,你可以实现 didReceiveMemoryWarning 这个函数。苹果官方文档请猛击

  总结下:iOS6 之前:

                          viewDidUnload  和 didReceiveMemoryWarning 都会被调用。

             iOS6 及其后面的版本。

                          viewDidUnload 不会被调用  didReceiveMemoryWarning 依然被调用。系统会自动处理view相关的内存,我们不用担心。

     苹果官方给出的解释了相关的方案总是看起来十分美好的,但是现实往往是残酷。

1.我们的工程是ARC的。

2.我们会在viewController里面持有大量子view的成员变量(strong)

3.我们实现了大量的viewDidUnload函数来释放 (2)里面持有的那个子view。

    让我们看看我们的代码到了iOS6以后会发生什么事情。因为所有的子view都是strong持有的,这样会导致,及时系统内存警告导致了view的回收,他们也不会被真正的释放。于是乎,我们的程序可能就在后台被系统频繁的杀死。

    分析到这里,解决方案也就很清楚了,我就不罗嗦了。贴段Apple给的解决方案代码。

 1 - (void)didReceiveMemoryWarning  
 2 {  
 3     [super didReceiveMemoryWarning];  
 4     // Add code to clean up any of your own resources that are no longer necessary.  
 5     if ([self.view window] == nil)  
 6     {  
 7         // Add code to preserve data stored in the views that might be  
 8         // needed later.  
 9         // Add code to clean up other strong references to the view in  
10         // the view hierarchy.  
11         self.view = nil;  
12     }  

那么有了上面的代码,事情结束了吗?没有。下面说下这个方案的问题。(一个例子)

    一个App 有 3个 tab,A 、B、C。(都从viewController继承,并且都实现了didReceiveMemoryWarning)。当程序启动的时候,默认显示tab A,这个时候,A 的 viewDidload被调用,并且加载数据显示给用户。然后我们切换到 tab B,B会重复A的加载过程。

      这时候系统产生了一个内存警告,A、B、C 3个对象都会受到警告。

A对象:因为它已经不在当前UI显示了,所以满足[self.view window] == nil,相关view被释放。

B对象:正在显示,所有didReceiveMemoryWarning什么也不会干。

C对象:最悲惨,从来没有显示过,viewDidload从来没调用过,也没有显示过。然后有个self.view .这句的调用会导致一个结果,就是C对象的viewDidload会被调用一次,于是他的逻辑就是释放前先创建一次,然后再把自己释放,是不是很悲剧。(所以apple给的方案也不一定完美靠谱)

到这里故事也讲了,最后说说,在iOS6 及其以后,我们应该怎么处理这个问题。

1.不要把 subView 当成成员变量来持有。使用tag来操作。(其实不管在哪个版本最后都这么做)

2.不需要实现viewDidUnload,由系统自己来控制相关的内存释放

3.在需要的时候实现didReceiveMemoryWarning来释放一些业务数据减少内存的占用,不要操作UIView。

   也许有错误,欢迎大家指正交流