Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【IOS开发基础系列】SDWebImageDownloader专题

【IOS开发基础系列】SDWebImageDownloader专题

作者头像
江中散人_Jun
发布于 2023-10-16 03:55:02
发布于 2023-10-16 03:55:02
8420
举报

1 机制原理

        SDWebImage是一个很厉害的图片缓存的框架。既ASIHttp+AsyncImage之后,我一直使用AFNetworking集成的UIImageView+AFNetworking.h,但后者对于图片的缓存实际应用的是NSURLCache自带的cache机制。而NSURLCache每次都要把缓存的raw  data 再转化为UIImage,就带来了数据处理和内存方面的更多操作。具体的比较在这里

        SDWebImage提供了如下三个category来进行缓存。

    • MKAnnotationView(WebCache)

    • UIButton(WebCache)

    • UIImageView(WebCache)

        以最为常用的UIImageView为例:

    1、UIImageView+WebCache: setImageWithURL: placeholderImage: options: 

    先显示 placeholderImage,同时由SDWebImageManager 根据 URL 来在本地查找图片。

    2、SDWebImageManager: downloadWithURL: delegate: options: userInfo:

    SDWebImageManager是将UIImageView+WebCache同SDImageCache链接起来的类,     SDImageCache:queryDiskCacheForKey:delegate:userInfo:

    用来从缓存根据CacheKey查找图片是否已经在缓存中

    3、如果内存中已经有图片缓存, SDWebImageManager会回调SDImageCacheDelegate: imageCache: didFindImage: forKey: userInfo:

    4、而 UIImageView+WebCache 则回调SDWebImageManagerDelegate:  webImageManager: didFinishWithImage: 来显示图片。

    5、如果内存中没有图片缓存,那么生成 NSInvocationOperation 添加到队列,从硬盘查找图片是否已被下载缓存。

    6、根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。

    7、如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。

    8、如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调imageCache:didNotFindImageForKey:userInfo:。

    9、共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。

    10、图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。

    11、connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。

    12、connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。

    13、图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。

    14、在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder: didFinishDecodingImage: userInfo: 回调给 SDWebImageDownloader。

    15、imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。

    16、通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。

    17、将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。

    18、写文件到硬盘在单独 NSInvocationOperation 中完成,避免拖慢主线程。

    19、如果是在iOS上运行,SDImageCache 在初始化的时候会注册notification 到 UIApplicationDidReceiveMemoryWarningNotification以及 UIApplicationWillTerminateNotification,在内存警告的时候清理内存图片缓存,应用结束的时候清理过期图片。

    20、SDWebImagePrefetcher 可以预先下载图片,方便后续使用。

2 开发技巧

2.1 常见问题

2.1.1 下载大量图片导致内存告警
2.1.1.1 问题原因

    1、CGBitmapContextCreateImage绘制的图片会造成内存无法释放,应该换用CGDataProviderCreateWithCFData;

    2、加载大量图片时,SD会将图片进行解压(加快渲染速度,但是内存会增大差不多一倍),然后将解压后的Image数据缓存在内存中,从而导致内存暴涨;

以下代码具有内存泄露问题:

    // 原始方案

    UIGraphicsBeginImageContextWithOptions(imageSize,YES, 0);

    [image drawInRect: imageRect];

    UIImage *imgData = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return imgData;

//   改进方案1

//        CGImageRef imgRef =CGImageCreateWithImageInRect(image.CGImage,CGRectMake(0,0,image.size.width,image.size.height));

//   

//       UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);

//        CGContextRef context = UIGraphicsGetCurrentContext();

//        CGContextDrawImage(context, imageRect, imgRef);

//    //   [image drawInRect: imageRect];

//        UIImage *imgData = UIGraphicsGetImageFromCurrentImageContext();

//        UIGraphicsEndImageContext();

//        CGImageRelease(imgRef);

//        UIImage *data = [self verticallyFlipImage: imgData];

//       

//        return data;

    //方案二,内存有释放,挂机

//   UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);   

//    CGContextRef context =UIGraphicsGetCurrentContext();

//    CGRect rect = CGRectMake(0, 0,imageSize.width * [UIScreen mainScreen].scale, imageSize.height * [UIScreenmainScreen].scale);

//    // draw alpha-mask

    CGContextSetBlendMode(context,kCGBlendModeNormal);

//    CGContextDrawImage(context, rect,image.CGImage);

//    // draw tint color, preserving alpha valuesof original image

    CGContextSetBlendMode(context,kCGBlendModeSourceIn);

//

//    CGContextFillRect(context, rect);

//   

//    //Set the original greyscale template asthe overlay of the new image

//    UIImage *imgData = [selfverticallyFlipImage:image];

//    [imgData drawInRect:imageRect];

//    UIImage *colouredImage =UIGraphicsGetImageFromCurrentImageContext();

//    UIGraphicsEndImageContext();

//    colouredImage = [selfverticallyFlipImage:colouredImage];

//    CGContextRelease(context);

//   

//    return colouredImage;

    //方案三,内存没释放

//    CGFloat targetWidth = imageSize.width *[UIScreen mainScreen].scale;

//    CGFloat targetHeight = imageSize.height *[UIScreen mainScreen].scale;

//    CGImageRef imageRef = [image CGImage]; 

//    CGBitmapInfo bitmapInfo =CGImageGetBitmapInfo(imageRef);  

//    CGColorSpaceRef colorSpaceInfo =CGImageGetColorSpace(imageRef);

//    CGContextRef bitmapContext;

//    bitmapContext = CGBitmapContextCreate(NULL,targetWidth, targetHeight,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef),colorSpaceInfo, bitmapInfo);

//    CGContextDrawImage(bitmapContext,CGRectMake(0, 0, targetWidth, targetHeight), imageRef);

//    CGImageRef imgref =CGBitmapContextCreateImage(bitmapContext);

//    UIImage* newImage = [UIImage imageWithCGImage: imgref];

//    CGColorSpaceRelease(colorSpaceInfo);

//    CGContextRelease(bitmapContext);

//    CGImageRelease(imgref);

//   

//   return newImage;

2.1.1.2 方案一:修改源代码,入缓存前做数据压缩

http://my.oschina.net/u/1244672/blog/510379

        SDWebImage有一个SDWebImageDownloaderOperation类来执行下载操作的。里面有个下载完成的方法:

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

    SDWebImageDownloaderCompletedBlockcompletionBlock = 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 0pixels"}], 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];

        UIImageOrientationorientation = [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];

2.1.1.3 方案二:设置全局缓存大小

http://www.myexception.cn/swift/2033029.html

    1、首先在appdelegate方法didFinishLaunchingWithOptions

SDImageCache.sharedImageCache().maxCacheSize=1024*1024*8设置一下最大的缓存大小。

    2、在appdelegate applicationDidReceiveMemoryWarning里加入

SDImageCache.sharedImageCache().clearMemory()

SDWebImageManager.sharedManager().cancelAll()

2.1.1.4 方案三:定时清理内存缓存

http://www.bubuko.com/infodetail-956863.html

        经过尝试,发现了一个最简单的完美解决该问题的方法

        在使用SDWebImage加载较多图片造成内存警告时,定期调用

 [[SDImageCache sharedImageCache] setValue: nil forKey: @"memCache"];

2.1.1.5 方案四(不推荐):修复SD库代码,不做解压,直接返回压缩的原图
2.1.1.6 方案五(推荐):使用CGDataProviderRef进行图形解压重绘

iOS开发中界面展示大图片时UIImage的性能有关问题

http://www.myexception.cn/operating-system/578931.html

#import "SDWebImageDecoder.h"

@implementation UIImage (ForceDecode)

+ (UIImage*) decodedImageWithImage: (UIImage*)image {

    if (image.images) {

       // Do not decode animated images

       return image;

    }

    //仅仅作为临时应付方案

    //    return image;

    UIImage *decompressedImage;

    @autoreleasepool{

        //核心代码,可以解决内存未释放问题

        NSData *data = UIImageJPEGRepresentation(image, 1);

        CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

        CGImageRefimageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO,

kCGRenderingIntentDefault);

    //    CGImageRef imageRef = image.CGImage;

    CGSizeimageSize = CGSizeMake(CGImageGetWidth(imageRef),CGImageGetHeight(imageRef));

    CGRect imageRect = (CGRect){.origin = CGPointZero, .size=imageSize};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

    intinfoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);

    BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || infoMask ==kCGImageAlphaNoneSkipFirst || infoMask ==kCGImageAlphaNoneSkipLast);

    // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.

    // https://developer.apple.com/library/mac/#qa/qa1037/_index.html

    if(infoMask == kCGImageAlphaNone&& CGColorSpaceGetNumberOfComponents(colorSpace)

> 1) {

        // Unset the old alpha info.

        bitmapInfo &= ~kCGBitmapAlphaInfoMask;

        // Set noneSkipFirst.

        bitmapInfo |= kCGImageAlphaNoneSkipFirst;

    }

     // Some PNGs tell us they have alpha but only 3 components. Odd.

    else if(!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace)

== 3) {

        // Unset the old alpha info.

        bitmapInfo &= ~kCGBitmapAlphaInfoMask;

        bitmapInfo |= kCGImageAlphaPremultipliedFirst;

    }

    // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.

    CGContextRef context = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height,  CGImageGetBitsPerComponent(imageRef), 0, colorSpace, bitmapInfo);

    CGColorSpaceRelease(colorSpace);

    // If failed, return undecompressed image

    if(!context) 

        return image;

    CGContextDrawImage(context,imageRect, imageRef);

    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);

    CGContextRelease(context);

    decompressedImage = [UIImage imageWithCGImage: decompressedImageRef scale: image.scale orientation: image.imageOrientation];

    CGImageRelease(decompressedImageRef);

}

//    CVPixelBufferRef pixelBuffer;

//   CreateCGImageFromCVPixelBuffer(pixelBuffer,&decompressedImageRef);

//    CGImage *cgImage =CGBitmapContextCreateImage(context);

//    CFDataRef dataRef =CGDataProviderCopyData(CGImageGetDataProvider(cgImage));

//    CGImageRelease(cgImage);

//    image->imageRef = dataRef;

//    image->image =CFDataGetBytePtr(dataRef);

    return decompressedImage;

}

3 参考链接

(GOOD)iOS开发中界面展示大图片时UIImage的性能有关问题

http://www.myexception.cn/operating-system/578931.html

(Good)iPhone - UIImage Leak, CGBitmapContextCreateImage Leak

http://stackoverflow.com/questions/1427478/iphone-uiimage-leak-cgbitmapcontextcreateimage-leak

Another iPhone - CGBitmapContextCreateImage Leak

http://stackoverflow.com/questions/1434714/another-iphone-cgbitmapcontextcreateimage-leak

UIGraphicsBeginImageContext vs CGBitmapContextCreate

http://stackoverflow.com/questions/4683448/uigraphicsbeginimagecontext-vs-cgbitmapcontextcreate

iPhone - CGBitmapContextCreateImage Leak, Anyone else withthis problem?

http://stackoverflow.com/questions/1431566/iphone-cgbitmapcontextcreateimage-leak-anyone-else-with-this-problem

Build and Analyze false positive on leak detection?

http://stackoverflow.com/questions/8438249/build-and-analyze-false-positive-on-leak-detection

iPhone - Multiple CGBitmapContextCreateImage Calls -ObjectAlloc climbing

http://stackoverflow.com/questions/1436465/iphone-multiple-cgbitmapcontextcreateimage-calls-objectalloc-climbing

(Good)ios开发图片处理,内存泄露

http://www.oschina.net/question/736524_69802

主题: CGBitmapContextCreateImage(bitmap)内存泄露问题处理

http://www.cocoachina.com/bbs/read.php?tid=31835

iOS异步图片加载优化与常用开源库分析

http://luoyibu.com/2015/05/12/iOS异步图片加载优化与常用开源库分析/

主题:图片处理开源函数ImageProcessing  CGDataProviderCreateWithData Bug修复

http://www.cocoachina.com/bbs/read.php?tid=116149

CGDataProviderCreateWithData对内存数据的释放

http://www.taofengping.com/2012/11/04/cgdataprovidercreatewithdata_memory_release/#.VmpqgoSitZE

IOS7.x下UIGraphicsGetImageFromCurrentImageContext引发内存暴涨,导致应用被结束掉

http://blog.163.com/l1_jun/blog/static/1438638820155593641529/

在iOS中与CGContextRef的内存泄漏

http://www.itstrike.cn/Question/55b86ce7-dfba-4548-a103-22dc5317420a.html

Quartz 2D (ProgrammingWithQuartz) note

http://renxiangzyq.iteye.com/blog/1188025

使用AFNetworking,SDWebimage和OHHTTPStubs

http://blog.shiqichan.com/using-afnetworking-sdwebimage-and-ohhttpstubs/

SDWebImage缓存图片的机制(转)

http://blog.csdn.net/zhun36/article/details/8900327

近来一个swift项目用uicollectionview 用sdwebimage 加载图片,发生内存猛增,直接闪退的情况,简单说一下解决方案

http://www.myexception.cn/swift/2033029.html

关于SDWebImage加载高清图片导致app崩溃的问题

http://www.bubuko.com/infodetail-956863.html

SDWebImage加载大图导致的内存警告问题

http://blog.csdn.net/richer1997/article/details/43481959

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

http://my.oschina.net/u/1244672/blog/510379

使用SDWebImage加载大量图片后造成内存泄露的解决办法

http://www.bubuko.com/infodetail-985746.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【IOS开发高级系列】异步绘制专题
用CGImageCreateCopy 或者CGImageCreateCopyWithColorSpace函数拷贝
江中散人_Jun
2022/03/08
1.5K0
【IOS开发高级系列】异步绘制专题
IOS开发系列——异步绘制专题
用CGImageCreateCopy或者CGImageCreateCopyWithColorSpace
江中散人_Jun
2022/03/08
1.5K0
IOS开发系列——异步绘制专题
iOS复习中有关SDWebImage可能知识点总结(2)
分为内存缓存(利用SDImageCache类的NSCache属性),磁盘缓存(利用NSFileManager),和操作缓存(利用runtime关联的字典属性)。下载之前先查询缓存,没有就下载并在下载后保存图片到缓存。
陈满iOS
2018/09/10
8610
iOS复习中有关SDWebImage可能知识点总结(2)
【IOS开发进阶系列】APP性能优化专题
        在iOS本地资源文件编译后放置与应用程序包(Bundle)文件中即<应用名>.app文件。
江中散人_Jun
2023/10/16
3890
【IOS开发进阶系列】APP性能优化专题
iOS开发 - 图片的解压缩到渲染过程
一.图像从文件到屏幕过程 通常计算机在显示是CPU与GPU协同合作完成一次渲染.接下来我们了解一下CPU/GPU等在这样一次渲染过程中,具体的分工是什么? CPU: 计算视图frame,图片解码,需要
猿_人类
2019/04/25
1.7K0
iOS开发 - 图片的解压缩到渲染过程
iOS复习中有关SDWebImage可能知识点总结(1)
例如,SD为UIImageView提供的UIImageView+WebCache.m分类,有这些API:
陈满iOS
2018/09/10
9440
iOS复习中有关SDWebImage可能知识点总结(1)
SDWebImage源码阅读-第三篇
这一篇讲讲不常用的一些方法。 1 sd_setImageWithPreviousCachedImageWithURL: placeholderImage: options: progress: completed: 取得上次缓存的图片,然后作为占位图的参数再次进行一次图片设置。 - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWe
王大锤
2018/05/17
1.4K0
iOS 图片加载框架SDWebImage详解
在使用SDWebImage加载图片时,尤其是加载gif等大图时,SDWebImage会将图片缓存在内存中,这样是非常吃内存的,这时我们就需要在适当的时候去释放一下SDWebImage的内存缓存,才不至于造成APP闪退。 SDWebImage 提供了 UIImageView、UIButton 、MKAnnotationView 的图片下载分类,只要一行代码就可以实现图片异步下载和缓存功能。 这样开发者就无须花太多精力在图片下载细节上,专心处理业务逻辑。
网罗开发
2021/01/29
2.7K0
最新版SDWebImage的使用
我之前写过一篇博客,介绍缓存处理的三种方式,其中最难,最麻烦,最占内存资源的还是图片缓存,最近做的项目有大量的图片处理,还是采用了SDWebImage来处理,但是发现之前封装好的代码报错了。研究发现,是我用了新版的SDWebImage,好多方法都变了。 现在把代码贴出来,供大家参考。尤其是新手,看完这篇博客,图片缓存so easy。最后有demo供大家下载,先学习。 第一步,下载SDWebImage,导入工程。github托管地址https://github.com/rs/SDWebImage 第二步,在需
王大锤
2018/05/17
9590
SDWebImage 图片下载缓存框架 常用方法及原理
功能:图片下载、图片缓存、下载进度监听、gif处理等等 项目地址:https://github.com/rs/SDWebImage 常见面试题: SDWebImage的最大并发数是多少? _dow
用户2141756
2018/05/18
3.3K0
iOS面试题:SDWebImage原理
减少网络流量,下载完图片后存储到本地,下载再获取同一张图片时,直接从本地获取,提升用户体验,能快速从本地获取呈现给用户。
猿_人类
2019/05/22
2.9K0
iOS面试题:SDWebImage原理
UIImage 图片处理:截图,缩放,设定大小,存储
图片的处理大概分 截图(capture), 缩放(scale), 设定大小(resize), 存储(save)
周希
2019/10/15
2.3K0
短视频直播源码,iOS图片去背景
Camera-on-Coffee-Table_1EBVyCTLzJiT.jpeg 短视频直播源码,iOS图片去背景相关的代码 - (UIImage *)removeBackgroudWithImage: (UIImage *)image{     unsigned char *targetData = malloc(sizeof(unsigned char) * image.size.width *image.size.height *4);     UIGraphicsBeginImageContex
yunbaokeji柯基
2020/11/20
6080
短视频直播源码,iOS图片去背景
iOS开发·由SDWebImage引发的知识点聚合与思考(最新呕心沥血之作)
学习iOS的各种知识点,例如runloop,只懂原理不行,要清楚明白它的应用场景才是真懂;学习SDWebImage的框架源码,只看SDWebImage的业务逻辑,也不是真懂。有效的学习是不断的问问题,挖掘并总结SDWebImage它这些场景涉及到的知识点,然后再模仿它,结合那些场景去写出这个知识点才是真懂。据我所观察SD涉及到的知识点就有:runloop的mode切换,runtime的关联对象,多线程NSOperation的开始与挂起,网络操作里面NSURLSession与NSURLConnection的区别,关于缓存的NSCache,NSFileManager操作,等等。
陈满iOS
2018/09/10
2.1K0
iOS开发·由SDWebImage引发的知识点聚合与思考(最新呕心沥血之作)
iOS实现毛玻璃效果,图片模糊效果的三种方法
App设计时往往会用到一些模糊效果或者毛玻璃效果,iOS目前已提供一些模糊API可以让我们方便是使用。
用户7705674
2021/10/29
2.7K0
SDWebImage源码分析 原
     SDWebImage是iOS开发中非常流行的一个网络图片加载库,如果你观察其源码,会发现其中的文件非常多,虽然文件数很多,但是作者的代码结构和条理却是非清晰。SDWebImage的代码结构基本可以分为3块:应用层类别、核心功能类、工具类与类别。其中我们最常使用的是应用层的类别。例如UIImageView的图片加载,UIButton的图片加载等。
珲少
2018/08/15
1K0
SDWebImage源码分析
                                                                            原
AFNetworking源码探究(十二) —— 数据解析之子类中协议方法的实现
上一篇讲述了一个AFURLResponseSerialization协议以及AFHTTPResponseSerializer和AFJSONResponseSerializer类中父类那个协议方法的实现。这一篇看一下剩下的那四个子类中该协议的实现。
conanma
2021/09/03
5400
[iOS源码笔记]·第三方网络图片处理框架:SDWebImage网络下载及缓存管理策略
typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
陈满iOS
2018/09/10
2.3K0
[iOS源码笔记]·第三方网络图片处理框架:SDWebImage网络下载及缓存管理策略
SDWebImage 引发的 cell不断下拉引起的闪退 卡顿
最近在我们的项目中出现了一个问题,暴力测试 高速上拉cell 不断加载出更多的cell  就会出现app 闪退。调试的时候 会发现 高速拉出很多cell的时候 内存 会有极大的浮动,拉出差不多200多个cell的时候就会出现闪退。为了弄清楚是怎么回事,我查了很多资料 ,也看了很多国外的博客 ,后来终于让我发现了问题所在,废话不多说 ,听我细细道来 1.首先是SDwebimage的原理: ---- UIImageView+WebCache:setImageWithURL:placeholderImage:op
陈雨尘
2018/06/01
1.3K0
SDWebImage源码阅读-第一篇
一 题外话   之前写过一篇最新版SDWebImage的使用,也简单的介绍了一下原理。这两天正梳理自己的知识网络,觉得有必要再阅读一下源码,一是看具体实现,二是学习一下优秀开源代码的代码风格,比如接口设计,设计模式,变量命名等等。   既然是第一篇,就要制定一个阅读源码的计划,以什么顺序阅读完全部代码。我们从最常见的入口切入sd_setImageWithURL,一路下去,最后再阅读没有设计到的部分。   在开始之前强烈建议先去读我之前的文章:最新版SDWebImage的使用。心里有个大概再去探讨细节,效果更
王大锤
2018/05/17
8180
推荐阅读
相关推荐
【IOS开发高级系列】异步绘制专题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档