iOS中基于UITableView的大批量数据加载优化
2013-09-04刘辰基周宝刚郭淑琴
刘辰基,周宝刚,郭淑琴
(1.浙江工业大学信息工程学院,浙江杭州310023;2.浙江科技学院,信息与电子工程学院,浙江杭州310023)
0 引言
iOS是苹果公司推出的手持设备操作系统。一方面,iOS设备提供给每个应用软件使用的内存是有限的[1],而且内存占用量过大的应用软件无法通过苹果公司的审核。另一方面,拥有良好的用户体验是应用软件大规模推广的基础。因此,在iOS应用软件的开发过程中,内存控制和用户体验是开发者需要时刻注意的两个方面。UITableView是一种表格视图,基本组成单元为UITableViewCell。无论是iOS设备自带的通讯录、备忘录、提醒事项等应用软件,还是第三方的微信、微博、陌陌等社交软件[2],都使用了这个视图。然而,在平时的开发过程中,使用UITableView加载大批量数据,经常会遇到由于内存占用量过大导致系统崩溃,以及用户体验较差的问题,因此有必要对该系统进行更深层面的优化。
1 存在的问题
问题一:应用软件在使用UITableView加载大批量数据的时候出现内存预警,继而运行崩溃。在数据量大的情况下,一些开发者直接将数据存放在内存中,随着不断地从服务器加载数据,占用的内存空间越来越大。同时,使用UITableView对数据进行显示时,根据数据个数创建相应数量的UITableView-Cell,也占用了很大的内存空间。这些造成了应用程序在使用UITableView加载大批量数据时内存占用过大。
问题二:加载数据时让用户处于等待状态,而且等待时间过长,用户体验较差。应用软件在使用UITableView加载大批量数据显示的过程中,先从服务器加载数据,加载成功后再使用UITableView进行显示。在从服务器加载数据的过程中,由于数据量大和网络状况的原因,耗费了一定的时间。另一方面,视图UITableView对大批量数据进行显示的过程,也耗费了过长的时间。这些耗费的时间一直让用户处于等待状态,造成了非常差的用户体验。
2 优化方案
2.1 内存的优化
首先,使用视图UITableView对数据进行显示时,开启重用机制。重用机制是iOS系统中UITable-View自带的一个机制,它在一定程度上能够节约内存,尤其是数据量大的时候[3]。
重用机制的核心是系统内部创建了NSMutableArray类型的_visiableCells和NSMutableDictionary类型的_reusableTableCells。系统根据cell对应的标识符(Identifier)加载UITableViewCell。当用户滑动屏幕时,滑出屏幕的cell从可见变为不可见,此时系统将cell从_visiableCells取出,和它对应的cell标识符组成一组键值,再放入_reusableTableCells;划入屏幕的cell从不可见变为可见,此时系统根据相应的cell标识符,从_reusableTableCells取出对应的cell放入_visiableCells,如果_reusableTableCells中没有,则创建一个新的cell,再放入_visiableCells。
开启重用机制后,由于_visiableCells和_reusableTableCells中的cell构成了一个循环重用,实际生成的cell总个数仅仅比屏幕中显示cell最多数量的情况下多出一两个,这对内存的节约是非常有效的。开启重用机制的代码如下:
static NSString*CellIdentifier=@ ”Cell”;
UITableViewCell*cell=[tableView dequeueResuableCellWithIdentifier:CellIdentifier];
if(cell==nil){
//创建新的cell
}
其次,对加载的数据进行存储,并将相应的内存及时释放。数据可以存放到SQLite数据库。当UITableView需要展示数据的时候,从相应的存储取出一条显示一条,这样可以一定程度的节约内存。另一方面,将这些数据进行存储,当用户需要再次读取这些数据时,就可以直接从存储读取,不必再次从服务器加载,有助于节省开销。
2.2 用户体验的优化
首先,分批次和多线程加载数据。当从服务器加载大批量数据到UITableView显示的时候,由于数据量大,如果一次性地从服务器加载所有数据,在网络状况不好的情况下,这一过程会耗费很长时间。此时,可以使用分批次加载,一次加载10条或者20条数据进行存储显示,然后再进行下次的加载。
在分批次加载数据时,使用多线程[4]。如果使用单线程,系统在执行加载数据请求时,对于其它请求而言,主线程处于阻塞状态,数据加载完成后,主线程才会执行其它请求,这导致用户在数据加载过程中处于等待状态,用户体验较差。开启多线程能够很好地解决这个问题。当进行查看下个批次数据操作的时候,开启一个新的线程去加载数据,加载结束后回到主线程调用[UITableView reloadData]对视图进行更新显示。在这种情况下,主线程没有阻塞,系统可以响应用户的其它请求,这是非常友好的。需要注意的是,此时更新视图的操作需要放到主线程进行,否则程序会运行崩溃。
其次,由于每条数据的长度不一定相同,这使得对应的UITableViewCell高度也不一定相同。因此,需要对cell的高度进行动态实现。cell的高度在UITableView Delegate相应函数中进行设置[5]。动态高度要处理得当,否则会造成UITableView显示过程耗费时间过长,用户体验较差。
一般情况下,动态高度的计算方法有两种。第一种方法的代码如下:
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{
UITableViewCell*cell=[self tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.frame.size.height;
}
第二种方法是在heightForRowAtIndexPath函数中根据数据动态地计算各个cell的高度。
当加载大批量数据的时候,选用第二种方法。因为第一种方法执行时,系统重新调用了UITable-View Data Source的-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath函数,这造成了该函数的多次调用,耗费时间。第二种方法是根据所要显示的数据直接计算出相应cell的高度,没有额外的开销。与第一种方法相比,在加载大数据的时候,第二种方法对性能影响较小。
同时,通过计算得到的高度要进行缓存处理。当调用[UITableView reloadData]对视图进行刷新显示时,系统会多次调用heightForRowAtIndexPath函数。如果高度进行了缓存处理,此时可以直接从缓存中读取,而不需要重新计算,这在加载大批量数据的时候,能够节约非常可观的时间,可以有效地提升系统性能和用户体验。
2.3 方案流程图
整个优化方案的流程图如图1所示。
图1 优化方案流程图
3 测试结果
使用Xcode自带的性能检测工具Instruments,可以非常直观地观察应用程序在运行时的内存使用情况[6]。整个测试过程中,应用程序使用视图UITableView从服务器加载320条数据进行显示。测试过程中其它部分都保持相同,唯一的区别是一种没有进行优化,另一种按照文中所给的优化方案流程进行了处理。最后测试结果显示,未进行优化时,内存使用情况如图2所示。按照优化方案进行处理后,内存使用情况如图3所示。
图2 优化前内存使用量
图3 优化后内存使用量
图3中,All Allocations是程序运行时所有分配的对象。Live Bytes表示当前存活对象在内存中所占用的字节数。Overall Bytes表示从程序开始运行,对象使用的总字节数,这里的对象包括已经销毁的和仍然存活的。程序所占用的内存为All Allocations类中,Live Bytes一栏所显示的数字。对比图2、3,可以清楚地看到,按照优化方案进行优化后,内存占用量减少。同时,按照优化方案处理后,用户等待时间减少,显示速度加快,用户体验得到提升。
4 结束语
本文针对iOS开发过程中,使用视图UITableView加载大批量数据时出现的内存占用量过大和用户体验差问题,分别从数据的加载、存储、展示3个方面出发,介绍了相应的优化方法。方法经过实际项目的测试,成功使应用程序在系统性能和用户体验方面得到了提升。在实际开发过程中,系统性能和用户体验的提升是没有止境的,这需要开发者根据实际情况进行相应的优化,从而开发出性能更加优良的应用程序。
[1]刘乐廷,李敬兆.IOS内存开发管理机制的研究[J].计算机与现代化,2013,29(3):196-199.
[2]李慧慧.3G时代手机传播的特性及模式分析[D].北京:北京邮电大学,2012:11-13.
[3]Dave Mark,Jeff LaMarche.漆振,解巧云,孙文磊,等译.iPhone开发基础教程[M].北京:人民邮电出版社,2009:50.
[4]XMobileApp.iPhone创意开发入门与实战[M].北京:人民邮电出版社,2010:395.
[5]Erica Sadun.漆振,解巧云,郎亚妹,等译.iPhone开发秘籍[M].北京:人民邮电出版社,2009:156.
[6]刘铭,朱舸,王佳.iPhone程序开发基础教程[M].北京:电子工业出版社,2011:11.