[iOS/OC]SDWebImage和LKImage对比

0x0背景

原本是放到自己博客的,不怎么用了,把文章同步过来,原文地址[iOS/OC]SDWebImage和LKImage对比

LKImageKit是腾讯开源的一个高性能图片加载框架,虽然第一时间下载了源码,但是只是简单的看了框架,没有细致的研读源码。最近空闲下来,学习了一下LKImageKit源码,其中有很多巧妙的实现。本文将通过1张图片的加载流程,对比两个图片框架。

0x1正文

LKImageKit和SDWebImage分别选用了两种不同的图片加载方案。LKImageKit的图片加载是提供了一个LKImageView,加载图片需要使用指定的容器。SDWebImage是写了一个Category,加载图片可以使用系统的UIImageView或其子类。流程上。

1.入口

发起一个图片加载,LKImageKit是在layoutSubviews时,发起1次图片加载,SDWebImage提供了1个主动发起图片加载请求的接口sd_setImageWithUrl

LKImageKit发起图片加载:

// 上层调用
imageView.URL = [NSURL urlWithString:@"https://xxx.png"];
imageView.request.synchronized = YES;

// 底层加载
- (void)layoutSubviews {
    [super layoutSubviews];
    [self layoutAndLoad];
}

SDWebImage发起图片加载

// 上层调用
[imageView sd_setImageWithURL:[NSURL URLWithString:@""]];

// 之后开始下载流程

两个图片库都提供了加载回调,不同的是,LKImageKit提供的是delegate的方法,SDWebImage提供的是callback

LKImageKit

@protocol LKImageViewDelegate <NSObject>
@optional

- (void)LKImageViewImageLoading:(LKImageView *)imageView request:(LKImageRequest *)request;
- (void)LKImageViewImageDidLoad:(LKImageView *)imageView request:(LKImageRequest *)request;

@end

SDWebImage

typedef void(^SDWebImageCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);

2.下载

LKImageKit进行图片下载会统一由LKImageManger进行管理,LKImageKit提供的请求合并的优化就是通过LKImageManager进行的。请求会通过blockOperation放到1个operationQueue中进行多个加载请求的队列管理。

资源加载则由LKImageLoader进行,由单例LKImageLoaderManager进行管理。网络下载是LKImageNetworkFileLoader进行,使用了NSURLSession,本地图片加载通过LKImageLocalFileLoader进行。

[requestLV2.loader dataWithRequest:requestLV2
                          callback:^(LKImageRequest *requestLV2, NSData *data, float progress, NSError *error) {
                              [self loadDataRequestFinished:requestLV2 data:data progress:progress error:error];
                          }];

SDWebImage进行图片下载由SDWebImageManager进行管理。类似的,在SDWebImage 5.0版本开始,也使用SDWebImageLoader进行加载,使用SDWebImageLoadersManager进行管理。网络下载使用SDWebImageDownloader进行。使用NSOperation进行下载管理。

[self downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:completedBlock];

对比可知,LKImageKit在下载前做了很多优化,下载流程的管理更加细腻。SDWebImage的下载过程由于历史原因,虽然在5.0上大刀阔斧的改造了很多东西,但是整体流程会显得更加笨重一些。

3.图片解码

LKImageKit和SDWebImage的图片解码大同小异,以LKImageKit为例:

// 由LKImageDecoderManager进行解码器的管理
UIImage *image = [decoder imageFromData:data request:request error:&decode_error];

// 普通静图
result = [UIImage imageWithData:data scale:[UIScreen mainScreen].scale];

// 1帧的动图
UIImage *image = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:orientation];

// 动图
UIImage *image = [UIImage animatedImageWithImages:images duration:INFINITY];

4.图片解压缩

图片解压缩是将解码后的image解出bitmap,从而避免系统主线程解压缩导致的主线程卡顿的问题。这里两个库也都是大同小异。以LKImageKit为例:

CGContextRef context = CGBitmapContextCreate(NULL, clipSize.width, clipSize.height, 8, 0, colorspace, bitmapInfo);
CGContextDrawImage(context, imageRect, input.CGImage);
CGImageRef cgimage = CGBitmapContextCreateImage(context);
UIImage *image = [UIImage imageWithCGImage:cgimage scale:screenScale orientation:input.imageOrientation];

不同的是,LKImageKit因为是用的指定的容器进行全链路的图片加载,所以可以通过打通全链路,在解压缩时,提前获取加载的容器大小,然后根据容器的大小进行按需解bitmap,从而节约内存。

开源SDWebImage并没有这个优化。我自己在SDWebImage上实现了一套类似的方案,需要从接口调用到解bitmap全链路打通,透传容器大小按需解码,以及对带alpha通道的webp图片等的异常case处理。略有不同的是,LKImageKit使用了image的scale属性,SDWebImage的scale默认1,需要做额外的pt->px的转换。后续有机会会把代码提到开源仓库。

0x2总结

两种图片方案有各自的业务场景和出发点,各有好处。

LKImageKit方案对图片的管理能力更强,图片加载的流程对于框架更加透明;SDWebImage方案更加灵活,尤其在5.0后,各种扩展性都非常好,LKImageKit的下载、解码管理有明显的借鉴SDWebImage的痕迹。另外,对于图片的加载流程,LKImageKit更加细腻,比如请求合并,按需解bitmap。

同时,从商业角度看,微信、QQ等大型App,是需要对图片加载全链路进行埋点监控的,这种强势掌控加载细节的LKImageKit方案,处理其这样的需求更加便利。猜想腾讯内部的LKImageKit版本应该还有埋点监控、网络接管等更多模块的适配接口,开源的只是删减了相关依赖的外部版本。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容