【iOS】didReceiveMemoryWarning实例方法

iPhone下每个App可用的内存是被限制的,如果一个App使用的内存超过20M,则系统会向该App发送Memory Warning(内存警告)消息,收到此消息后,App必须正确处理,否则可能出错或出现内存泄漏。

目录

    • 流程
    • iOS 6以上版本的App对内存警告处理方法
    • 相关方法
      • loadView
      • loadView
      • viewDidLoad
      • awakeFromNib
      • initWithCoder
    • 结论


官方文档:

请添加图片描述

重写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上:

  1. 如果viewController未显示(在后台),会执行didRecieveMemoryWarning -> viewDidUnload,前者会自动将viewController的view及其所有子view全部销毁
  2. 如果viewController当前正在显示(在前台),则只执行didRecieveMemoryWarning ,viewController的view不会被销毁
  3. 当重新显示该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之前:viewDidUnloaddidReceiveMemoryWarning都会被调用。
  • iOS 6之后:viewDidUnload不会被调用didReceiveMemoryWarning依然被调用。系统会自动处理View相关的内存,我们不用担心。也就是说不再支持viewDidUnload了。
    官方文档的解释是:系统会自动控制大的View所占用的内存,其他小的View所占用的内存是极其微小的,不值得为了省内存而去清理然后在重新创建。 如果你需要在内存警告的时候释放业务数据或者做些其他的特定处理,你可以实现didRecieveMemory方法。

苹果官方给出的相关解释方案总是美好的,但现实往往是残酷的:

  1. 我们的工程是ARC的。
  2. 我们会在viewController里面强持有(strong)大量子View得成员变量
  3. 我们实现了大量的viewDidUnload函数来释放(2)里面持有的那个子View

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

栗子🌰:

一个App有三个tab(选项卡界面元素,比如“首页”、“通知”和“消息”的tabs):tabA、tabB、tabC(都从viewController继承,并且都实现了didRecieveMemoryWarning)。当程序启动时,默认显示tabA,这时,tabA的viewDidLoad被调用,并且加载数据显示给用户,然后切换到tabB,B会重复A的加载过程。
这时系统产生了一个内存警告,tabA、tabB、tabC三个对象都会受到警告。

  • tabA对象:因为它已经不在当前UI显示了,所以满足[self.view window] == nil,相关View被释放。
  • tabB对象:正在显示,所有didReceiveMemoryWarning什么也不会干。
  • tabC对象:最悲惨,从来没有显示过,viewDidLoad从来没调用过,也没有显示过。然后有个self.view .这句的调用会导致一个结果,就是C对象的viewDidLoad会被调用一次,于是他的逻辑就是释放前先创建一次,然后再把自己释放,是不是很悲剧。(所以apple给的方案也不一定完美靠谱)。

iOS 6之后,应该做的:

  1. 不要把子View当成员变量来持有,使用tag来操作(其实不管在哪个版本最后都这么做)。
  2. 不需要实现viewDidLoad,由系统自己来控制相关的内存释放。
  3. 在需要的时候实现didRecieveMemory来释放一些业务数据减少内存的占用,不要操作UIView。

相关方法

loadView

loadView

viewDidLoad

awakeFromNib

initWithCoder

正在学习…loadView / viewDidLoad / awakeFromNib / initWithCoder 总结

结论

所以流程应该是这样:
(loadView/nib文件)来加载view到内存 ——>viewDidLoad函数进一步初始化这些view ——>内存不足时,调用viewDidUnload函数释放views —->当需要使用view时又回到第一步

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6、xss-labs之level8

1、测试分析 传入123查看页面源码&#xff0c;发现传入的值传给了value和a标签的href&#xff0c;并且对特殊字符<>" 都进行了HTML实体化&#xff0c;对于大小写进行了转化&#xff0c;过滤掉了src、data、onfocus、href、script、"&#xff08;双引号&#…

AI图书推荐:终极ChatGPT企业手册—借助Python和Java实现

《终极ChatGPT企业手册—借助Python和Java实现》&#xff08;Ultimate ChatGPT Handbook for Enterprises&#xff09;是一本关于ChatGPT的手册&#xff0c;旨在帮助企业利用AI能力、提示工程和ChatGPT的解决方案循环来改变企业景观。这本书提供了深入探讨ChatGPT的演变、能力以…

webpack5基础和开发模式配置

运行环境 nodejs16 webpack基础 webpack打包输出的文件是bundle 打包就是编译组合 webpack本身功能 仅能编译js文件 开始使用 基本配置 五大核心概念 准备webpack配置文件 1.在根目录 2.命名为webpack.config.js 开发模式介绍 处理样式资源 处理css样式资源文件…

算法-可完成的最大任务数

一解析&#xff1a; 为了尽可能多的完成任务&#xff0c;充分利用时间&#xff0c;越早越好&#xff0c;所以从项目开启的那一天起就开始做任务&#xff0c;一直做到项目结束为止。 但是&#xff0c;对于第i天来说&#xff0c;若可执行的任务有多个&#xff0c;该如何选择&am…

C语⾔:内存函数

1. memcpy使⽤和模拟实现&#xff08;对内存块的复制&#xff0c;不在乎类型&#xff09; void * memcpy ( void * destination, const void * source, size_t num ); • 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 • 这个函数在遇…

3D Slicer:从入门到精通——数据模块之DICOM

DICOM 文章目录 DICOM概述DICOM简介Slicer DICOM数据库DICOM插件 如何操作创建DICOM数据库将DICOM文件读入场景DICOM导入DICOM加载 从DICOM数据库中删除数据将数据从场景导出到DICOM数据库将数据从场景导出到DICOM文件DICOM网络传输DICOMweb网络传输 查看DICOM元数据 面板及其用…

指定目录匹配文件并批量导入

需求描述: 1,需要从某个目录以某种正则表达式匹配到所有文件 2,将这些文件批量上传 3,上传完成后需要返回上传的地址 1,引入依赖 <!-- 测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

R实验 参数估计

实验目的&#xff1a; 掌握矩法估计与极大似然估计的求法&#xff1b;了解估计量的优良性准则&#xff1a;无偏性、有效性、相合性&#xff08;一致性&#xff09;&#xff1b;学会利用R软件完成一个正态总体均值和两个正态总体均值差的区间估计&#xff1b;学会利用R软件完成…

NiuCloud-Admin-SAAS:引领前端技术革新与SaaS应用快速开发的未来

一、引言 在数字化快速发展的今天&#xff0c;企业对于快速搭建、高效运营的SaaS&#xff08;Software-as-a-Service&#xff09;系统的需求日益增长。为满足这一需求&#xff0c;NiuCloud-Admin-SAAS作为一款快速开发SaaS通用管理系统后台框架&#xff0c;凭借其先进的技术栈…

基于Java实现震中附近风景区预警可视化分析实践

目录 前言 一、空间数据说明 1、表结构信息展示 2、空间范围查询 二、Java后台开发实现 1、模型层设计与实现 2、控制层设计与实现 三、Leaflet地图开发 1、地震震中位置展示 2、百公里风景区列表展示 3、风景区列表展示 4、附近风景区展示 四、总结 前言 地震这类…

【区块链】webase-front

因为WeBASE是基于Java开发的&#xff0c;故依赖于Java运行环境&#xff0c;支持版本JDK 8至JDK 14。 我们安装JDK 8。在Linux终端中&#xff0c;使用如下命令安装开源版本JDK 8 apt update apt install -y openjdk-8-jdk 安装JDK8后&#xff0c;需要设置JAVA_HOME环境变量&am…

链表mark

什么是链表&#xff0c;链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后一个节点的指针域指向null&#xff08;空指针的意思&#xff09;。…

[数智人文实战] 02.舆情分析之词云可视化、文本聚类和LDA主题模型文本挖掘

【数智人文与文本挖掘】知识星球建立且正式运营,欢迎新老博友和朋友加入,一起分享更多数智人文知识和交流进步。该星球计划每周至少分享7个资源或文章,包括数智人文、文本挖掘、人工智能、大数据分析和图书情报的技术文章、代码及资源。同时,欢迎进入星球的朋友咨询我图情和…

Java开发错误经验积累

业务平时积累 为什么用StringUtils来判断字符串是否为空 在 Java 中,当一个字符串为 null 时,调用它的方法会出现空指针异常。例如: String str = null; if (str.isEmpty()) {// ... }在上面的示例中,由于 str 为 null,调用它的 isEmpty() 方法会出现空指针异常。 为了…

操作系统课程实验1-进程调度模拟实验

操作系统课程实验1-进程调度模拟实验 一、实验介绍 1.1 实验目的 本实验模拟在单处理机环境下的处理机调度&#xff0c;帮助理解进程调度的概念&#xff0c;深入了解进程控制块的功能&#xff0c;以及进程的创建、撤销和进程各个状态间的转换过程。 1.2 实验内容 进程调度算…

NDIS小端口驱动开发(一)

在四种NDIS相关的驱动中&#xff0c;微型端口驱动(也经常翻译为为小端口驱动)位于驱动栈的底部&#xff0c;一般将它理解为NIC设备的驱动程序&#xff1a; 有几种类型的微型端口驱动程序类型&#xff1a; 无连接微型端口驱动程序用于控制无连接网络媒体 &#xff0c;如以太网的…

【量算分析工具-方位角】GeoServer改造Springboot番外系列六

【量算分析工具-概述】GeoServer改造Springboot番外系列三-CSDN博客 【量算分析工具-水平距离】GeoServer改造Springboot番外系列四-CSDN博客 【量算分析工具-水平面积】GeoServer改造Springboot番外系列五-CSDN博客 【量算分析工具-方位角】GeoServer改造Springboot番外系列…

题解:CF1968F(Equal XOR Segments)

题解&#xff1a;CF1968F&#xff08;Equal XOR Segments&#xff09; 题目翻译&#xff1a;定义一个序列是好&#xff0c;当且仅当可以将其分成大于 1 1 1 份&#xff0c;使得每个部分的异或和相等。现在给定一个长度为 n n n 的序列 a a a&#xff0c;以及 q q q 次查询…

redis基本数据结构与应用

文章目录 概要String结构Hash结构List结构Set结构Zset结构bitmap位图类型geo地理位置类型其他常用命令 概要 redis常用的5种不同数据结构类型之间的映射如下&#xff1a; 结构类型结构存储的值结构的读写能力STRING可以是字符串、整数或者浮点数key-value形式&#xff1b;对整…

JMH304-剑侠情缘2网络版+2017纹饰端+翅膀+单机+外网整理+各种副本

资源介绍&#xff1a; 藏剑-太虚-梁山-杀手堂种树地宫师门纹饰装备长流云阳套等等———– 做登录器联系站长 资源截图&#xff1a; 下载地址