SDWebImage 大家都用過,加載網(wǎng)絡(luò)圖片的一個類庫,非常好用,可是在一些比較特殊的情況下就會出現(xiàn)一些不足,如下情況:
app 很多地方的網(wǎng)絡(luò)圖片都需要在顯示時候進行描邊處理或者圓角處理(直接設(shè)置layer圓角,多了會導致table卡頓,所以通常是在圖片上做手腳),而圖片的加載顯示剛好用的SDWebImage,這時候問題就來了,SDWebImage緩存的圖片是原圖,每次在顯示時候?qū)D片進行加工然后顯示,其實是很糟糕的做法,完全可以在緩存圖片前處理好,顯示時候直接拿來用。
這里介紹的就是未處理這個功能,新版不知道是不是支持這種情況。
怎么搞呢,分析源碼吧,網(wǎng)上很多介紹很詳細的文章,我這邊簡單說一下:
關(guān)鍵函數(shù)如下圖:

這個函數(shù)是獲取一手圖片文件的地方,代碼還有點多

做法很簡單,就是在這個方法的這個block 獲取到圖片時候用另外一個block把圖片傳到調(diào)用的地方,加工后再返回回來,緩存這個新圖片,如圖:

這樣基本達滿足前邊描述的情況了,
但是如果這一張圖片在多個地方使用,而且這些個地方對圖片的處理有事不一樣的時候就不行了,比方有的描邊有的圓角。
怎么辦呢,
在設(shè)置圖片的地方再加個參數(shù)key來標記圖片處理操作類型
這個處理起來比較簡單,只需要搞一下原本緩存的key就可以了,原本是醬紫的:

搞成醬紫就可以了:

然后設(shè)置函數(shù)把兩個新的參數(shù)補上去救ok了,為了不影響原來的結(jié)構(gòu),新建了一個分類,新增了這么個下載函數(shù)如下圖:

然后擴展一下設(shè)置圖片的方法就完美了如下:
- (void)sd_setImageWithURL:(NSURL *)url processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil processKey:processKey processBlock:processBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil processKey:processKey processBlock:processBlock] ;
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil processKey:processKey processBlock:processBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock processKey:processKey processBlock:processBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock processKey:processKey processBlock:processBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock processKey:processKey processBlock:processBlock];
}
設(shè)置函數(shù)里的總?cè)肟诟囊幌?/p>
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock {
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey_Process, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (!(options & SDWebImageDelayPlaceholder)) {
dispatch_main_async_safe(^{
self.image = placeholder;
});
}
if (url) {
// check if activityView is enabled or not
if ([self showActivityIndicatorView]) {
[self addActivityIndicator];
}
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
[wself removeActivityIndicator];
if (!wself) return;
dispatch_main_sync_safe(^{
if (!wself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
wself.image = image;
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
} processKey:processKey processBlock:processBlock];
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else {
dispatch_main_async_safe(^{
[self removeActivityIndicator];
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
然后聲明一下頭文件就好了,
.m文件遇到一些屬性找不到弄個延展引進來就好了如下:

有點多,為了方便,沒辦法,人家本來就這么多,oc下只能一個個搞。
這么一來就可以完美滿足前邊描述的情況了。
ps:SDWebImage 版本 3.8.2,后邊的情況不知道如何,就還沒更新。