网站后台图片模板,中国建设教育协会的网站查询,wordpress 搜索页,手机软件设计用什么软件iPhone下每个App可用的内存是被限制的#xff0c;如果一个App使用的内存超过20M#xff0c;则系统会向该App发送Memory Warning#xff08;内存警告#xff09;消息#xff0c;收到此消息后#xff0c;App必须正确处理#xff0c;否则可能出错或出现内存泄漏。 目录 流程…iPhone下每个App可用的内存是被限制的如果一个App使用的内存超过20M则系统会向该App发送Memory Warning内存警告消息收到此消息后App必须正确处理否则可能出错或出现内存泄漏。 目录 流程iOS 6以上版本的App对内存警告处理方法相关方法loadViewloadViewviewDidLoadawakeFromNibinitWithCoder 结论 官方文档 重写didReceiveMemoryWarning方法
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.NSLog(didReceiveMemoryWarning);
}流程
当应用可用内存过低导致系统发出内存警告的时候便会触发didReceiveMemoryWarning方法。App收到内存警告会调用
UIApplication::didRecieveMemoryWarning - UIApplicationDelegate::applicationDidRecieveMemoryWarning
然后调用当前所有的viewController进行处理因此处理的主要工作在viewController。 创建viewController时执行顺序是loadView - viewDidLoad。 当收到内存警告时didRecieveMemoryWarning会判断当前viewController的view是否显示在window上
如果viewController未显示在后台会执行didRecieveMemoryWarning - viewDidUnload前者会自动将viewController的view及其所有子view全部销毁如果viewController当前正在显示在前台则只执行didRecieveMemoryWarning viewController的view不会被销毁当重新显示该viewController时执行过viewDidLoad的viewController即原来在后台会重新调用loadView - viewDidLoad。
iOS 6以上版本的App对内存警告处理方法
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning]; //super调用的此方法即使没有显示在window上在后台也不会自动的将self.view释放。//此处做兼容处理需要加上iOS 6.0的宏开关保证是在6.0下使用的6.0以前屏蔽以下代码否则会在下面使用self.view时自动加载viewDidUnLoadif ([[UIDevice currentDevice].systemVersion floatValue] 6.0) {//需要注意的是self.isViewLoaded是必不可少的其他方式访问视图会导致它加载 在WWDC视频也忽视这一点。if (self.isViewLoaded !self.view.window) { // 是否是正在使用的视图//codeself.view nil;// 目的是再次进入时能够重新加载调用viewDidLoad函数。}}
}iOS 6之前viewDidUnload和didReceiveMemoryWarning都会被调用。iOS 6之后viewDidUnload不会被调用didReceiveMemoryWarning依然被调用。系统会自动处理View相关的内存我们不用担心。也就是说不再支持viewDidUnload了。 官方文档的解释是系统会自动控制大的View所占用的内存其他小的View所占用的内存是极其微小的不值得为了省内存而去清理然后在重新创建。 如果你需要在内存警告的时候释放业务数据或者做些其他的特定处理你可以实现didRecieveMemory方法。
苹果官方给出的相关解释方案总是美好的但现实往往是残酷的
我们的工程是ARC的。我们会在viewController里面强持有strong大量子View得成员变量我们实现了大量的viewDidUnload函数来释放2里面持有的那个子View
让我们看看我们的代码到了iOS6以后会发生什么事情。因为所有的子View都是strong持有的这样会导致即使系统内存警告导致了View的回收他们也不会被真正的释放。于是乎我们的程序可能就在后台被系统频繁的杀死。
栗子 一个App有三个tab选项卡界面元素比如“首页”、“通知”和“消息”的tabstabA、tabB、tabC都从viewController继承并且都实现了didRecieveMemoryWarning。当程序启动时默认显示tabA这时tabA的viewDidLoad被调用并且加载数据显示给用户然后切换到tabBB会重复A的加载过程。 这时系统产生了一个内存警告tabA、tabB、tabC三个对象都会受到警告。 tabA对象因为它已经不在当前UI显示了所以满足[self.view window] nil相关View被释放。tabB对象正在显示所有didReceiveMemoryWarning什么也不会干。tabC对象最悲惨从来没有显示过viewDidLoad从来没调用过也没有显示过。然后有个self.view .这句的调用会导致一个结果就是C对象的viewDidLoad会被调用一次于是他的逻辑就是释放前先创建一次然后再把自己释放是不是很悲剧。所以apple给的方案也不一定完美靠谱。 iOS 6之后应该做的
不要把子View当成员变量来持有使用tag来操作其实不管在哪个版本最后都这么做。不需要实现viewDidLoad由系统自己来控制相关的内存释放。在需要的时候实现didRecieveMemory来释放一些业务数据减少内存的占用不要操作UIView。
相关方法
loadView
loadView
viewDidLoad
awakeFromNib
initWithCoder
正在学习…loadView / viewDidLoad / awakeFromNib / initWithCoder 总结
结论
所以流程应该是这样 (loadView/nib文件)来加载view到内存 ——viewDidLoad函数进一步初始化这些view ——内存不足时调用viewDidUnload函数释放views —-当需要使用view时又回到第一步