接上一篇翻译的内容。缓存
再次运行测试
性能优化
在重用cell以后,你能够再一次测试滚动性能。从表格3-3能够看出,在你正确重用cell以后,性能提高了一倍。
网络
表格 3-3 重用cell以后测试的结果多线程
结果显示你的作法是正确的;可是,如今的性能依然不够好。你老是想让性能上升至0.6666-0.0001左右;对于一个标准的UITableViewCell这是一个正常的性能,就像在第一部分展现的那样。因此下一部分将要学习如何重用p_w_picpaths,而不是每次调用的时候都建立一个新的p_w_picpath。
app
这就是你为何要重用cell的缘由。对于OS来讲,建立和加载一个新的cell到内存中,都是要花费时间和内存资源的。这就是为何tableview老是queue 一个cell进行重用,不管这个cell是否在屏幕以外。若是你重用cell,OS就不须要建立一个新的cell来显示;它只须要获取旧的cell,改变一些属性,而后从新显示这个cell。这个过程比OS建立一个新的cell要快的多。ide
重用图片性能
显示图片的主要问题在于加载的时间,要么经过文件系统IO,要么经过网络IO,都是很是耗时的。这个加载过程一样会影响到滚动性能,当iOS不能返回cell来渲染UI时。学习
因为这个缘由,请参考ReuseImageViewController这个给工程。首先我解释一下在这些例子中,我为何没有使用[UIImage p_w_picpathd:@""]。p_w_picpathNamed作了一项很是重要的工做:它会在内存中缓存图片,当你再次访问的时候会重用它。使用这个方法的问题是它只能从bundle中获取文件 --- 换句话说,图片只能和app的源代码放在一块儿。一般,你必须调用方法[UIImage alloc] initWithContentsOfFile:@""];或者[UIImage alloc] initWithData:data]]。调用这些方法,OS不会自动的在内存中缓存图片。测试
因此,我但愿你经过一个小的dictionary在内存中存储图片,来本身缓存图片(请看第4章)。另一个图片处理很是重要的部分是多线程(请看第6章)。使用这个技术,你能够把耗时的的处理任务放到当前线程以外。在个人当前例子中,不会使用多线程,由于你必须当即了解不少新的概念。在本章结束的时候,你应该本身作完这个练习。优化
这是在NSDictionary缓存图片的主要代码(请不要使用这种方式存储图片,由于它会致使内存警告)。
// Code to store the p_w_picpath in the dictionary- (UIImage *)p_w_picpathWithName:(NSString *)name {
if ([self.p_w_picpathDictionary objectForKey:name]) {return [self.p_w_picpathDictionary objectForKey:name];
}
UIImage *p_w_picpath = [[UIImage alloc] initWithContentsOfFile:name];[self.p_w_picpathDictionary setObject:p_w_picpath forKey:name];
return p_w_picpath;
}
下面这个是提取最近一次图片的主要代码。
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CellIdentifier";
ReuseTableViewCell *cell = (ReuseTableViewCell *) [selfgetCellWithTableView:tableView cellIdentifier:CellIdentifier nibName:@"ReuseTableViewCell"];
NSString *avatarFile = [NSString stringWithFormat:@"a0"];
NSString *avatarName = [[NSBundle mainBundle] pathForResource:avatarFile ofType:@"jpeg"];
cell.avatar.p_w_picpath = [self p_w_picpathWithName:avatarName];
cell.userName.text = [NSString stringWithFormat:@"hi here: %d", indexPath.row];// Configure the cell.
return cell;
}
代码更新以后,你再运行一下测试。从表格3-4来看,你获得了一个更好的结果。如今的平均运行时间是0.002,fps的性能如今接近60。和以前的ReuseTableView相比,你获得了一个更好的性能。
表格 3-4 在重用图片以后的测试结果
好极了!fps如今几乎是60了,预加载的时间也下降了。若是你的apps可以达到这个水平,你没必要再担忧滚动时的性能了;它很是的流畅。一般,对于一个正常的,简单的里面包含不少subviews的UITableView来讲,这已是一个很是好的性能了。这样是很是好的,由于你没必要在开始的时候就作不少工做。若是滚动的性能依然很差,你就必须使用一个更好可是更复杂的方式来达到一样的性能。
正如在第1章和第2章提到的,你应该老是当心谨慎,避免过分优化。为了一个很小的性能优化而浪费太多的时间是很是不值得的。所以从这点考虑,若是你的应用依然存在滚动性能方面的问题,你应该转到第2个例子,它使用到了UITableViewCell的绘制技术。
减小预加载时间
一般,我会经过缓存来重用图片,同时减小初始化的过程。当OS须要为TableView渲染一个新的cell,会经过调用下面的方法来返回一个新的cell:
- (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Initialize and return the Cell here
}
所以,若是你在这里阻塞了太长的时间,UserInterface渲染的过程就会被阻塞;它将不能作任何事情或显示任何新的东西。这就是为何用户看到在某个地方滚动中止的缘由。
为了使这个过程尽量的快,你能够去除一些逻辑,延迟计算,经过重用来缓存数据和图片。另一个方法是经过首先使用默认的图片和数据来重用cell。当要获取图片或数据的时候,你可使用多线程,而后稍后进行填充。从用户的角度来看,这种方法将会使得滚动更加流程,加载图片的速度更快。
第二个例子
当你有不少subviews或使用老的设备,绘制一个自定义的cell可以提高应用程序的性能。对于iPhone4和之后的设备,有一个很是显著的性能提高,所以你将会看到绘制自定义cell技术会有一个很大的不一样。
在这个例子中,我会增长cells的复杂度,这是来自一个真实的应用,每个cell有10个subviews,包括图片和文件。所以,你会看到不少真实的应用(像Facebook,这是咱们尝试模拟的),滚动性能会被复杂的subviews结构严重影响到。我测试的应用有一个相似图 3-5这样的一个用户界面。
图 3-5 第二个应用例子
每个cell包含一个头像,用户名,邮件的图片,标题和内容。它同时也显示了应用发送邮件的时间。测试结果图表格3-5。
表格3-6显示了运行自定义绘制代码的结果
从表格3-5和3-6能够看出,使用自定义绘制代码可以显著的提高渲染性能。在使用复杂的subview这点上,这个性能已经足够好了,你没必要须要其余的优化了。
对于没有优化的cell,它将会建立不少的components和subviews。请查看图3-5,确保你理解了这个问题。
暂时翻译到这里,有时间继续!