日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题

發布時間:2024/1/17 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉載至?http://www.superqq.com/blog/2015/01/22/jie-jue-mwphotobrowserzhong-de-sdwebimagejia-zai-da-tu-dao-zhi-de-nei-cun-jing-gao-wen-ti/

MWPhotoBrowser是一個非常不錯的照片瀏覽器,在github的star接近3000個,MWPhotoBrowser下載

MWPhotoBrowser來加載小圖1M以下的都應該不會有內存警告的問題。如果遇到大圖,3M、4M、5M的大圖,很有可能導致內存警告。最近我就遇到這個問題,很是頭疼。來回滑動查看照片內存飆到100M以上:

?

網上查了很多資料,都沒有解決問題。

我們來看一下MWPhotoBrowser,其實MWPhotoBrowser用的是SDWebImage來下載圖片的。SDWebImage下載

在github看到SDWebImage的介紹,后面說到:

Future Enhancements

?

? ? LRU memory cache cleanup instead of reset on memory warning

看到這個真是欲哭無淚啊。

再去看看SDWebImage的,有個人提問了:

How to disable "memory cache"?? I don't want memory cache,? it used a lot of memory and got memory waring easily,? disk is enough for me...

有人回答:

There is no way to disable the memory cache. But the cache is designed to flush itself when you get a memory warning, so you shouldn't need to worry it.

說的是SDWebImage遇到內存警告會自動釋放內存,但是這還是解決不了問題,加載大圖的時候,內存會突然蹦到100多M,在4s及以下的手機上跑,再就掛了。

還是沒有解決內存警告的問題。怎么辦呢?

我是這么解決的:

SDWebImage有一個SDWebImageDownloaderOperation類來執行下載操作的。里面有個下載完成的方法:

- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection {

?? SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock;

?? @synchronized(self) {

?? ? ? CFRunLoopStop(CFRunLoopGetCurrent());

?? ? ? self.thread = nil;

?? ? ? self.connection = nil;

?? ? ? [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil];

?? }

?

?? if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) {

?? ? ? responseFromCached = NO;

?? }

?

?? if (completionBlock)

?? {

?? ? ? if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) {

?? ? ? ? ? completionBlock(nil, nil, nil, YES);

?? ? ? }

?? ? ? else {

?? ? ? ? ? UIImage *image = [UIImage sd_imageWithData:self.imageData];

?? ? ? ? ? NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];

?? ? ? ? ? image = [self scaledImageForKey:key image:image];

?

?? ? ? ? ? // Do not force decoding animated GIFs

?? ? ? ? ? if (!image.images) {

?? ? ? ? ? ? ? image = [UIImage decodedImageWithImage:image];

?? ? ? ? ? }

?? ? ? ? ? if (CGSizeEqualToSize(image.size, CGSizeZero)) {

?? ? ? ? ? ? ? completionBlock(nil, nil, [NSError errorWithDomain:@"SDWebImageErrorDomain" code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES);

?? ? ? ? ? }

?? ? ? ? ? else {

?? ? ? ? ? ? ? completionBlock(image, self.imageData, nil, YES);

?? ? ? ? ? }

?? ? ? }

?? }

?? self.completionBlock = nil;

?? [self done];

}

其中,UIImage *image = [UIImage sd_imageWithData:self.imageData];就是將data轉換成image。

再看看sd_imageWithData:這個方法:

+ (UIImage *)sd_imageWithData:(NSData *)data {

?? UIImage *image;

?? NSString *imageContentType = [NSData sd_contentTypeForImageData:data];

?? if ([imageContentType isEqualToString:@"image/gif"]) {

?? ? ? image = [UIImage sd_animatedGIFWithData:data];

?? }

#ifdef SD_WEBP

?? else if ([imageContentType isEqualToString:@"image/webp"])

?? {

?? ? ? image = [UIImage sd_imageWithWebPData:data];

?? }

#endif

?? else {

?? ? ? image = [[UIImage alloc] initWithData:data];

?? ? ? UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data];

?? ? ? if (orientation != UIImageOrientationUp) {

?? ? ? ? ? image = [UIImage imageWithCGImage:image.CGImage

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? scale:image.scale

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? orientation:orientation];

?? ? ? }

?? }

?

?

?? return image;

}

這個方法在UIImage+MultiFormat里面,是UIImage的一個類別處理。這句話很重要image = [[UIImage alloc] initWithData:data]; SDWebImage把下載下來的data直接轉成image,然后沒做等比縮放直接存起來使用。所以,我們只需要在這邊做處理即可:

UIImage+MultiFormat添加一個方法:

+(UIImage *)compressImageWith:(UIImage *)image

{

?? float imageWidth = image.size.width;

?? float imageHeight = image.size.height;

?? float width = 640;

?? 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;

?

}

然后在:image = [[UIImage alloc] initWithData:data];下面調用以下:

if (data.length/1024 > 1024) {

?? ? ? ? ? image = [self compressImageWith:image];

?? ? ? }

當data大于1M的時候做壓縮處理。革命尚未成功,還需要一步處理。在SDWebImageDownloaderOperation的connectionDidFinishLoading方法里面的:

? UIImage *image = [UIImage sd_imageWithData:self.imageData];

?

? //將等比壓縮過的image在賦在轉成data賦給self.imageData

? NSData *data = UIImageJPEGRepresentation(image, 1);

? self.imageData =? [NSMutableData dataWithData:data];

大工告成,我們來看一下效果吧:

?

果然問題得以解決。

更多iOS開發相關技術請關注iOS開發微信公眾號 iOS開發 :

iOSDevTip

Posted by 李剛 Jan 22nd, 2015 11:23 am ios開發

本文出處剛剛在線:http://www.superqq.com/blog/2015/01/22/jie-jue-mwphotobrowserzhong-de-sdwebimagejia-zai-da-tu-dao-zhi-de-nei-cun-jing-gao-wen-ti/

?

自由轉載-請在開頭注明本文出處。

轉載于:https://www.cnblogs.com/Camier-myNiuer/p/5100721.html

總結

以上是生活随笔為你收集整理的解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。