[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

相關文章
相關標籤/搜索