Men的博客

欢迎光临!

0%

AFN SD做了哪些优化

AFN包括如下模块

网络通信模块(AFURLSessionManager、AFHTTPSessionManger)
网络状态监听模块(Reachability)
网络通信安全策略模块(Security)
网络通信信息序列化/反序列化模块(Serialization)
对于iOS UIKit库的扩展(UIKit)

AFN优点

AFNetworking内置支持JSON,plist文件和XML文件的解析,使用比
较方便我们能够有效的控制并观察一个网络请求的创建、进行、取消、
完成、暂停恢复、异常等问题及状态
可以帮助我们轻松友好的完成请求的创建、响应的系列化,网络状态的监控以
及安全策略以及每一个请求operation的管理(operation的相互依赖或
状态改变)。 

SDWebImage 概论

1.提供了一个UIImageView的category用来加载网
络图片并且对网络图片的缓存进行管理
2.采用异步方式来下载网络图片
3.采用异步方式,使用memory+disk来缓存网
络图片,自动管理缓存。
4.支持GIF动画
5.支持WebP格式
6.同一个URL的网络图片不会被重复下载
7.失效的URL不会被无限重试
8.耗时操作都在子线程,确保不会阻塞主线程
9.使用GCD和ARC
10.支持Arm64
13.图片解码处理在一个 NSOperationQueue 完成,
不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,
最好也在这里完成,效率会好很多。

AFN、SD缺点

最近版早早已经支持NSURLSession了,但是不支持iOS7以下系统。
且AFNetworking必须使用ARC
SDWebImage 对gif的处理主要是在UIImage+GIF
这个文件里面,利用ImageIO函数创建二进制数据,如下:
由于SDWebImage通过动图数组来实现动态,
会造成内存不能及时释放
SDWebimage -静态图片加载会产生拉伸

SD下载完图片为什么要解码

在我们使用 UIImage 的时候,创建的图片通常不会直接加载到内存,而是在
渲染的时候再进行解压并加载到内存。这就会导致 UIImage 在渲染的时候效
率上不是那么高效。为了提高效率通过 decodedImageWithImage方法把图
片提前解压加载到内存,这样这张新图片就不再需要重复解压了,提高了渲染效
率。这是一种空间换时间的做法。

旧版本AFN为什么加Runloop

首先我们知道在旧版本的AFN中使用了 NSURLConnection 来发起并处理网
络连接。AFN 的做法是把网络请求的发起和解析都放在同一个子线程中进行,
但由于子线程默认不开启 runloop,它会向一个 C语言程序那样在运行完所有
代码后退出线程。而网络请求是异步的,这会导致获取到请求数据时,线程已经
退出,代理方法没有机会执行。因此,AFN 的做法是使用一个 runloop 来保
证线程不死,也就是下面这段被讲烂了的代码:

AFN多重代理如何实现

https://www.jianshu.com/p/961cfc9a446b
又有小伙伴问了,我们设置的这个代理不是NSURLSessionDelegate吗?怎
么能响应NSUrlSession这么多代理呢?我们点到类的声明文件中去看看:
我们可以看到这些代理都是继承关系,而在NSURLSession实现中,只要设置
了这个代理,它会去判断这些所有的代理,是否respondsToSelector这些代
理中的方法,如果响应了就会去调用。

SDWebImage的缓存策略

Memory 和 Disk 双缓存    

SDWebImage加载图片的流程

1.入口 setImageWithURL:placeholderImage:options:会
先把 placeholderImage显示,然后 SDWebImageManager根
据 URL 开始处理图片。
2.进入SDWebImageManager 类中
downloadWithURL:delegate:options:userInfo:,交给
SDImageCache从缓存查找图片是否已经下载
queryDiskCacheForKey:delegate:userInfo:.
3.先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,
SDImageCacheDelegate回调 
imageCache:didFindImage:forKey:userInfo:到
SDWebImageManager。
4.SDWebImageManagerDelegate 回调
webImageManager:didFinishWithImage: 到 
UIImageView+WebCache,等前端展示图片。
5.如果内存缓存中没有,生成 `NSOperation `
添加到队列,开始从硬盘查找图片是否已经缓存。
6.根据 URL的MD5值Key在硬盘缓存目录下尝试读取图片文件。这
一步是在 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中,内存缓存和硬盘缓存同时保
存。写文件到硬盘 也在以单独 NSOperation 完成,避免拖慢主
线程。
18.SDImageCache 在初始化的时候会注册一些消息通知,
在内存警告或退到后台的时 候清理内存图片缓存,应用结束的时候
清理过期图片。

SDWebimage对相同url图片问题

找出问题所在了,因为修改头像后,图片的url是不变的,而默认情
况下,SDWebimage对相同url是优先使用缓存的,因此得加
options属性
[self.HeaderImage sd_setImageWithURL:[NSURL URLWithString:yhPic] placeholderImage:[UIImage imageNamed:@"ameng_dh"] options:SDWebImageRefreshCached];
SDWebImageRefreshCached是专门用来处理相同url,图片不同
的情况的。
重点是在SDWebImageManager.m文件中,大概176行左右
在(利用SDWebImageRefreshCached)的基础上,修改SD库
添加这一段代码// remove 
SDWebImageDownloaderUseNSURLCache flag 
downloaderOptions &= 
~SDWebImageDownloaderUseNSURLCache;