iOS sd_WebImage大画像のロード時にメモリが急上昇する解決方法
3113 ワード
SDWebImageは誰もが熟知していることを憎んでいるに違いない.国内外の多くのAppが画像のロードに使用している.
しかし、最近、使用中にSDWebImageで複数の画像をロードしていることがわかりました.マイクロブログのダイナミックなように、ロード中です.画像の解像度が比較的大きい場合(画像が大きいわけではない)、何枚かの画像をロードするとクラッシュすることに気づいた.
ネット上では、画像をロードするたびにmemcacheをクリアすることができますが、効果はよくありません.
ここでは次の方法を採用しています.
SDWebImageDownloaderOperationのconnectionDidFinishLoadingメソッドの中にあります.
最後に再配合[[SDImageCache sharedImageCache]setValue:nil forKey:@"memCache"];(画像をロードして使用する)大功告成、親測メモリは基本的に大きく変化せず、自動放出も間に合う
waring!!!注意:この方法は慎重に使ってください.そうしないと、あなたのすべての画像が圧縮されて展示されるときははっきりしません.この方法の原理は画像の品質を圧縮することによって実現される.しかし、私はこの方法を採用しないほうがいいと思います.自分で小さな図をロードする必要があるところにマークをつけてsdを教えない限り、この時にsdを修正する必要があります.皆さんはこの考えで行うことができますが、修正するのは面倒かもしれません.
しかし、最近、使用中にSDWebImageで複数の画像をロードしていることがわかりました.マイクロブログのダイナミックなように、ロード中です.画像の解像度が比較的大きい場合(画像が大きいわけではない)、何枚かの画像をロードするとクラッシュすることに気づいた.
ネット上では、画像をロードするたびにmemcacheをクリアすることができますが、効果はよくありません.
[[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];
ここでは次の方法を採用しています.
ステップ1:UIImage+MultiFormatクラスに以下の圧縮方法を追加
+(UIImage *)compressImageWith:(UIImage *)image {
float imageWidth = image.size.width;
float imageHeight = image.size.height;
float width = 320;
float height = image.size.height/(image.size.width/width);
float widthScale = imageWidth /width;
float heightScale = imageHeight /height;
// bitmap context
// context
UIGraphicsBeginImageContext(CGSizeMake(width, height));
if (widthScale > heightScale) {
[image drawInRect:CGRectMake(0, 0, imageWidth /heightScale , height)];
}else {
[image drawInRect:CGRectMake(0, 0, width , imageHeight /widthScale)];
}
// context
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// context
UIGraphicsEndImageContext();
return newImage;
}
ステップ2:圧縮メソッドを次の方法で呼び出します。
+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {
if (!data) {
return nil;
}
UIImage *image;
SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:data];
if (imageFormat == SDImageFormatGIF) {
image = [UIImage sd_animatedGIFWithData:data];
}
#ifdef SD_WEBP
else if (imageFormat == SDImageFormatWebP){
image = [UIImage sd_imageWithWebPData:data];
}
#endif
else {
image = [[UIImage alloc] initWithData:data];
image = [[UIImage alloc] initWithData:data];
if (data.length/1024 > 90) {
image = [self compressImageWith:image];
}
UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data];
if (orientation != UIImageOrientationUp) {
image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation];
}
}
return image;
}
ステップ3:
SDWebImageDownloaderOperationのconnectionDidFinishLoadingメソッドの中にあります.
UIImage *image = [UIImage sd_imageWithData:self.imageData];
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
image = [self scaledImageForKey:key image:image];
NSData *data = UIImageJPEGRepresentation(image, 1);
self.imageData = [NSMutableData dataWithData:data];
最後に再配合[[SDImageCache sharedImageCache]setValue:nil forKey:@"memCache"];(画像をロードして使用する)大功告成、親測メモリは基本的に大きく変化せず、自動放出も間に合う
waring!!!注意:この方法は慎重に使ってください.そうしないと、あなたのすべての画像が圧縮されて展示されるときははっきりしません.この方法の原理は画像の品質を圧縮することによって実現される.しかし、私はこの方法を採用しないほうがいいと思います.自分で小さな図をロードする必要があるところにマークをつけてsdを教えない限り、この時にsdを修正する必要があります.皆さんはこの考えで行うことができますが、修正するのは面倒かもしれません.