[iOS Animation]-CALayer 图像IO一

图像IO

潜伏期值得思考 - 凯文 帕萨特git

在第13章“高效绘图”中,咱们研究了和Core Graphics绘图相关的性能问题,以及如何修复。和绘图性能相关紧密相关的是图像性能。在这一章中,咱们将研究如何优化从闪存驱动器或者网络中加载和显示图片。github

加载和潜伏

绘图实际消耗的时间一般并非影响性能的因素。图片消耗很大一部份内存,并且不太可能把须要显示的图片都保留在内存中,因此须要在应用运行的时候周期性地加载和卸载图片。网络

图片文件加载的速度被CPU和IO(输入/输出)同时影响。iOS设备中的闪存已经比传统硬盘快不少了,但仍然比RAM慢将近200倍左右,这就须要很当心地管理加载,来避免延迟。工具

只要有可能,试着在程序生命周期不易察觉的时候来加载图片,例如启动,或者在屏幕切换的过程当中。按下按钮和按钮响应事件之间最大的延迟大概是200ms,这比动画每一帧切换的16ms小得多。你能够在程序首次启动的时候加载图片,可是若是20秒内没法启动程序的话,iOS检测计时器就会终止你的应用(并且若是启动大于2,3秒的话用户就会抱怨了)。oop

有些时候,提早加载全部的东西并不明智。好比说包含上千张图片的图片传送带:用户但愿可以可以平滑快速翻动图片,因此就不可能提早预加载全部图片;那样会消耗太多的时间和内存。性能

有时候图片也须要从远程网络链接中下载,这将会比从磁盘加载要消耗更多的时间,甚至可能因为链接问题而加载失败(在几秒钟尝试以后)。你不可以在主线程中加载网络形成等待,因此须要后台线程。优化

线程加载

在第12章“性能调优”咱们的联系人列表例子中,图片都很是小,因此能够在主线程同步加载。可是对于大图来讲,这样作就不太合适了,由于加载会消耗很长时间,形成滑动的不流畅。滑动动画会在主线程的run loop中更新,因此会有更多运行在渲染服务进程中CPU相关的性能问题。动画

清单14.1显示了一个经过 UICollectionView 实现的基础的图片传送器。图片在主线程中 -collectionView:cellForItemAtIndexPath: 方法中同步加载(见图14.1)。atom

清单14.1 使用UICollectionView实现的图片传送器spa


复制代码

#import "ViewController.h"@interface ViewController() <UICollectionViewDataSource>@property (nonatomic, copy) NSArray *imagePaths;
@property (nonatomic, weak) IBOutlet UICollectionView *collectionView;@end@implementation ViewController- (void)viewDidLoad
{    //set up data
    self.imagePaths =
    [[NSBundle mainBundle] pathsForResourcesOfType:@"png" inDirectory:@"Vacation Photos"];    //register cell class
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{    return [self.imagePaths count];
}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath
{    //dequeue cell
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];    //add image view
    const NSInteger imageTag = 99;
    UIImageView *imageView = (UIImageView *)[cell viewWithTag:imageTag];    if (!imageView) {
        imageView = [[UIImageView alloc] initWithFrame: cell.contentView.bounds];
        imageView.tag = imageTag;
        [cell.contentView addSubview:imageView];
    }    //set image
    NSString *imagePath = self.imagePaths[indexPath.row];
    imageView.image = [UIImage imageWithContentsOfFile:imagePath];    return cell;
}@end

复制代码


 


图14.1 运行中的图片传送器

传送器中的图片尺寸为800x600像素的PNG,对iPhone5来讲,1/60秒要加载大概700KB左右的图片。当传送器滚动的时候,图片也在实时加载,因而(预期中的)卡动就发生了。时间分析工具(图14.2)显示了不少时间都消耗在了 UIImage 的 +imageWithContentsOfFile: 方法中了。很明显,图片加载形成了瓶颈。

图14.2

相关文章
相关标签/搜索