移动设备终端的内存极为有限,应用程序必须做好low-memory处理工作,才能避免程序因内存使用过大而崩溃。

low-memory 处理思路
通常一个应用程序会包含多个view controllers,当从view跳转到另一个view时,之前的view只是不可见状态,并不会立即被清理掉,而是保存在内存中,以便下一次的快速显现。但是如果应用程序接收到系统发出的low-memory warning,我们就不得不把当前不可见状态下的views清理掉,腾出更多的可使用内存;当前可见的view controller也要合理释放掉一些缓存数据,图片资源和一些不是正在使用的资源,以避免应用程序崩溃。

思路是这样,具体的实施根据系统版本不同而略有差异,本文将详细说明一下iOS 5与iOS 6的low-memory处理。

iOS 5 的处理
在iOS 6 之前,如果应用程序接收到了low-memory警告,当前不可见的view controllers会接收到viewDidUnload消息(也可以理解为自动调用viewDidUnload方法),所以我们需要在 viewDidUnload 方法中释放掉所有 outlets ,以及可再次创建的资源。当前可见的view controller 通过didReceiveMemoryWarning 合理释放资源,具体见代码注释。

举一个简单的例子,有这样一个view controller:
@interface MyViewController : UIViewController {  
    NSArray *dataArray;  
}  
@property (nonatomic, strong) IBOutlet UITableView *tableView;  
@end

对应的处理则为:
#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
    self.tableView = nil;
    dataArray = nil;
    
    [super viewDidUnload];
}

iOS 6 的处理
iOS 6 废弃了viewDidUnload方法,这就意味着一切需要我们自己在didReceiveMemoryWarning中操作。
具体应该怎么做呢?

1.将 outlets 置为 weak
当view dealloc时,没有人握着任何一个指向subviews的强引用,那么subviews实例变量将会自动置空。

@property (nonatomic, weak) IBOutlet UITableView *tableView;

2.在didReceiveMemoryWarning中将缓存数据置空
#pragma mark -   
#pragma mark Memory management   
  
  
- (void)didReceiveMemoryWarning  
{  
    [super didReceiveMemoryWarning];  
    // Dispose of any resources that can be recreated.   
    dataArray = nil;  
}

不要忘记一点,每当tableview reload 的时候,需要判断一下 dataArray ,若为空则重新创建。

兼容iOS 5 与 iOS 6
好吧,重点来了,倘若希望程序兼容iOS 5 与 iOS 6怎么办呢? 这里有一个小技巧,我们需要对didReceiveMemoryWarning 做一些手脚:

#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    
    if ([self isViewLoaded] && self.view.window == nil) {
        self.view = nil;
    }
    
    dataArray = nil;
}

判断一下view是否是window的一部分,如果不是,那么可以放心的将self.view 置为空,以换取更多可用内存。

这样会是什么现象呢?假如,从view controller A 跳转到 view controller B ,然后模拟low-memory警告,此时,view controller A 将会执行self.view = nil ; 当我们从 B 退回 A 时, A 会重新调用一次 viewDidLoad ,此时数据全部重新创建,简单兼容无压力~~

怎样处理iOS 5与iOS 6的 low-memory的更多相关文章

  1. iOS开发 - 兼容iOS 10

    1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserN ...

  2. iOS 1 到 iOS 10 ,我都快老了

    iOS 1:iPhone诞生 虽然很难想像,但初代iPhone在问世时在功能方面其实远远落后于那时的竞争对手,比如Windows Mobile.Palm OS.塞班.甚至是黑莓.它不支持3G.多任务. ...

  3. IOS学习之IOS沙盒(sandbox)机制和文件操作

    IOS学习之IOS沙盒(sandbox)机制和文件操作(一) 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都 ...

  4. 【译】UI设计基础(UI Design Basics)--iOS应用解析(iOS App Anatomy)(三)

    2.1  iOS应用解析(iOS App Anatomy) 几乎所有的iOS应用都会用到UIKit框架中的组件.了解这些基础组件的名称,角色,功能可以帮你在应用界面设计时做出更好的决策. UIKit提 ...

  5. IOS学习:ios中的数据持久化初级(文件、xml、json、sqlite、CoreData)

    IOS学习:ios中的数据持久化初级(文件.xml.json.sqlite.CoreData) 分类: ios开发学习2013-05-30 10:03 2316人阅读 评论(2) 收藏 举报 iOSX ...

  6. IOS 动画专题 --iOS核心动画

    iOS开发系列--让你的应用“动”起来 --iOS核心动画 概览 通过核心动画创建基础动画.关键帧动画.动画组.转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等.在今天的文章里您可以看 ...

  7. IOS开发笔记 IOS如何访问通讯录

    IOS开发笔记  IOS如何访问通讯录 其实我是反对这类的需求,你说你读我的隐私,我肯定不愿意的. 幸好ios6.0 以后给了个权限控制.当打开app的时候你可以选择拒绝. 实现方法: [plain] ...

  8. iOS开展 - 中国 iOS/Mac 开发博客列表

    博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 破船之家 http://beyondvincent.com/atom.xml NSHipster h ...

  9. Project support for both iOS 6 and iOS 7

    原文:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/S ...

随机推荐

  1. 数据绑定以及Container.DataItem几种方式与使用方法分析

    灵活的运用数据绑定操作        绑定到简单属性:<%#UserName%>        绑定到集合:<asp:ListBox id="ListBox1" ...

  2. Ubuntu14.04更新源

    Ubuntu14.04更新源 http://jingyan.baidu.com/article/7f41ecec1b7a2e593d095ce6.html Ubuntu源 http://wiki.ub ...

  3. delphi如何加上spliter分割条,任意调整大小

    如题1:如何把一个panel分割成四个小的panle 2:也就是如何加上spliter,分割条,任意调整大小 3.如何有独立的handle使用多个总共5个为什么呢,你放4个panel 然后放split ...

  4. Linux服务安全之TcpWrapper篇

    一.TcpWrapper的定义 任何以xinetd管理的服务都可以通过TcpWrapper来设置防火墙.简单地说,就是针对源IP或域进行允许或拒绝的设置,以决定该连接是否能够成功实现连接. 通过名称我 ...

  5. 基于visual Studio2013解决C语言竞赛题之1037数组求列和

          题目 解决代码及点评 /* 功能:已知有三个数组A,B,C,A为5行5列的二维数组,B.C为只有5个元素的一维数组,键盘输入数据的顺序如下: 23,45,6,1,- ...

  6. mysql数据导出权限问题

    mysql数据导出的方法有非常多,比如mysqldump, mysql -e 'sql' > file, 这些都能够非常方便的导出数据,但是在使用普通用户导出数据的时候,出现了问题. 1 sel ...

  7. poj 3466 A Simple Problem with Integers

    题目链接:http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 思路 ...

  8. asp.net2.0安全性(1)--用户角色篇(代码实现2)--转载来自车老师

    加载所有用户 MembershipUserCollection user = Membership.GetAllUsers(); listUser.DataSource = user; listUse ...

  9. Linux 静态库&动态库调用

    1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...

  10. css 水平居中的办法

    <div style="width: 100%; text-align: center; margin: auto;"> <div style="dis ...