首先我们来看iOS加载一张图片所经历的过程:(下面所讲述的代码基本以 imageWithContentsOfFile 方法来举例)
数据加载
- 我们优先创建UIImageView,把获得的图像数据赋值UIImageView
- 识别到我们缓冲区没有数据,就会去从磁盘拷贝数据到缓冲区
- 然后加载我们的图片
- 拿到了图片,下面到了视图渲染
视图渲染
- 图片数据在CoreAnimation流水线中,执行如下流程
- 优先计算视图Frame,进行视图构建和图片格式转换
- 如果图像未解码,则优先解码成位图数据
- 进行打包处理,主线程Runloop将其提交给Render Server
- 在提交之前,如果数据没有字节对齐,CoreAnimation会再拷贝一份数据,进行字节对齐
- 然后经过GPU图形渲染管线处理以后将渲染结果放入
帧缓冲区 然后视频控制器会按照VSync信号逐行读取帧缓冲区的数据,给显示器显示
从上述渲染过程中,我寻找其可优化点。
- 图像解码
- 内存加载
- 对齐字节
1.图像解码
当你用 UIImage 或 CGImageSource 的那几个方法创建图片时,图片数据并不会立刻解码。图片设置到 UIImageView 或者 CALayer.contents 中去,并且 CALayer 被提交到 GPU 前,CGImage 中的数据才会得到解码。这一步是发生在主线程的,并且不可避免。那么当需要加载的图片比较多时,就会对我们应用的响应性造成严重的影响,尤其是在快速滑动的列表上,这个问题会表现得更加突出。
iOS默认会在主线程对图像进行解码。解码过程是一个相当复杂的任务,需要消耗非常长的时间。由于在主线程超过16.7ms的任务会引起掉帧,所以我们把解码操作从主线程移到子线程,让耗时的解码操作不占用主线程的时间,解码的核心方法如下:
CGContextRef CGBitmapContextCreate(
void * data, //这块内存用于存储被绘制的图形,这块内存的size最小不能小于bytesPerRow*height(图形每行的字节数乘以图形的高度),传递NULL意味着由这个函数来管理图形的内存,这可以减少内存泄漏的问题;
size_t width, //图形的width
size_t height,//图形的height
size_t bitsPerComponent, //像素的每个颜色分量使用的 bit 数,在 RGB 颜色空间下指定 8 即可
size_t bytesPerRow,//位图的每一行使用的字节数,大小至少为 width * bytes per pixel 字节。有意思的是,当我们指定 0 时,系统不仅会为我们自动计算,而且还会进行 cache line alignment 的优化
CGColorSpaceRef _Nullable space, //就是我们前面提到的颜色空间,一般使用 RGB 即可;
uint32_t bitmapInfo//是一个枚举,
)
异步解码上代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSString *imagePath = self.imagePaths;
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, YES, 0);
[image drawInRect:imageView.bounds];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
});
});
虽说能够正常解压,但是我们也会发现一个问题,就是大图片的解压,所以这个地方安装苹果和各大三方代码中的提示要分为2种情况讨论:
1.对于小于60M的图片我们直接对图片解码,下面是SD的代码
+ (UIImage *)decodedImageWithImage:(UIImage *)image {
if (![self shouldDecodeImage:image]) {
return image;
}
CGImageRef imageRef = [self CGImageCreateDecoded:image.CGImage];
if (!imageRef) {
return image;
}
UIImage *decodedImage = [[UIImage alloc] initWithC
优化iOS图片加载:内存映射、异步解码与字节对齐

最低0.47元/天 解锁文章
624

被折叠的 条评论
为什么被折叠?



