Instruments Time profiler 调优APP 之图片解码

  • 以前闲时用instruments的Time profiler调试过APP,发现用tableView: cellForRowAtIndexPath: 中cell的图片设置耗时较多,之前改了一下,如下
dispatch_async(dispatch_get_global_queue(0, 0), ^{
        UIImage *cellImage = [UIImage imageNamed: self.imageNamesArray[indexPath.row] ];
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = cellImage;
        });
    });

    发现没什么效果,就没去改了(这就是不求甚解,?),直到最近被人问到图片的显示流程,去网上搜索相关资料,才发现用imageNamed的这种方式创建的图片,并不会立即解码,而是发生在CALayerPrepareCommit后 提交到GPU之前,才会去解码,那样总是会在主线程解码的,参考图片网址,参考YYKit大神写的文章

 

   后来在GitHub上面搜到了一种解决方案,就是在后台线程先把图片绘制到 CGBitmapContext 中,然后从 Bitmap中直接创建图片,UIImage+ImmediateDecode.m中主要代码如下

+ (instancetype)imageWithName:(NSString*)name{
    
    NSString *imgPath = [[NSBundle mainBundle] pathForResource:name ofType:nil];
    
    if ( !imgPath ) {
        imgPath = [[NSBundle mainBundle] pathForResource:name ofType:@"png"];
    }

    if (!imgPath) {
        imgPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@2x" ,name] ofType:@"png"];
    }
    
    if (!imgPath) {
        imgPath = [[NSBundle mainBundle] pathForResource:name ofType:@"jpg"];
    }
    
    return [UIImage  initImmediateLoadWithContentsOfFile: imgPath];
}



+ (UIImage*) initImmediateLoadWithContentsOfFile:(NSString*)path {
    UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
    CGImageRef imageRef = [image CGImage];
    CGRect rect = CGRectMake(0.f, 0.f, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
                                                       rect.size.width,
                                                       rect.size.height,
                                                       CGImageGetBitsPerComponent(imageRef),
                                                       CGImageGetBytesPerRow(imageRef),
                                                       CGImageGetColorSpace(imageRef),
                                                       kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
                                                       );
    //kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little are the bit flags required so that the main thread doesn't have any conversions to do.
    
    CGContextDrawImage(bitmapContext, rect, imageRef);
    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(bitmapContext);
    UIImage* decompressedImage = [[UIImage alloc] initWithCGImage: decompressedImageRef scale:2.0 orientation:UIImageOrientationUp];

    CGImageRelease(decompressedImageRef);
    CGContextRelease(bitmapContext);
    
    return decompressedImage;
}

   tableView: cellForRowAtIndexPath: 中的代码改为如下 

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        UIImage *tempImage = [UIImage imageWithName:self.imageNamesArray[indexPath.row]];
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = tempImage;
            [cell setNeedsLayout];
            [cell layoutIfNeeded];
        });
    });
  • Tips:
  1.  imageNamed:的方式对图片名称要求比较松,可以自动识别2x、3x的图片,以及png不带后缀都可以;但是以[[NSBundle mainBundle] pathForResource:@"myCamera" ofType:@"png”] 如果图片是myCamera@2x的话,则获取的路径为空
  2. Instruments 底部的call tree 设置一般勾选第2、3、4项;call tree constraints 可以设置最小的耗时操作如16ms 
  3. Instruments 鼠标框选时间轴中的某部分可以只看选中区域的耗时操作;Option + Click 智能展开或折叠call tree

转载于:https://www.cnblogs.com/Apple2U/p/9147343.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值