SDWebImage的实现机制以及解决tableView卡的问题和实现图片的缓存机制
2016-07-12 12:07
399 查看
SDWebImage内部实现过程:
1>.入口setImageWithUrl:placeHolderImage:options:会把placeHolderImage显示,然后SDWebImageManager根据URL开始处理图片.
2>.进入SDWebImageManager-downloadWithURL:delegate:options:userInfo:交给SDImageCache从缓存查找图片是否已经下载queryDiskCacheForKey:delegate:userInfo:
3>.先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate回调imageCache:didFineImage:forKey:userInfo:到SDWebImageManager.
4>.SDWebImageManagerDelegate回调webImageManager:didFinishWithImage:到UIImageView + WebCache等前端展示图片.
5>.如果内存缓存中没有,生成NSInvocationOperation添加到队列开始从硬盘查找图片是否已经缓存
6>.根据URLKey在硬盘缓存目录下尝试读取图片文件.这一步是在NSOperation进行的操作,所以回主线程进行结果回调notifyDelegate.
7>.如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小 会先清空内存缓存).SDImageCacheDelegate 回调imageCache:didFinishImage: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中内存缓存和硬盘缓存同时保存,写文件到硬盘也在以单独NSInvocationOperation完成,避免拖慢主线程
18>.SDImageCache在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片
19>.SDWI也提供UIButton + WebCache和MKAnnptation + WebCache方便使用
20>.SDWebImagePrefetcher 可以预先下载图片,方便后续使用
如何解决tableView卡,通过设置最大并发数,设置当前页的cell,而不是把所有cell一次性设置完,以及数据图片的三级缓存,直接保存在内存中和沙盒缓存中进行读取,降低网络请求的次数,不仅仅节约用户流量,也会保证tableView滑动的流动性
2.SDWebImage怎么样实现图片的缓存机制的?
图片的缓存,内存缓存,沙盒缓存,操作缓存,以tableViewController为例
每次cell需要显示,都需要重新调用-(UITableViewCell*)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath{}方法
每次调用tableView显示行的数据源方法时,如果需要从网络加载图片,就需要将加载图片这样的耗时操作放在子线程上执行,从网络上下载的图片可以以键值对的形式保存在定义的可变字典中,将每张图片的唯一的路径作为键,将从网络下载下来的图片作为值,保存在内存缓存中,这样每次滑动rtableViewcell 重用时就直接判断内存缓存中有没有需要的图片,如果有就不需要再次下载,在没有出现内存警告或者程序员手动清理内存缓存时,就直接从内存缓存中获取图片
为了每次退回程序,再次进入程序时,不浪费用户的流量,需要将第一次进入程序时加载的图片保存在本地沙盒缓存文件中,在沙盒中保存的图片数据没有被改变之前,下次开启程序就直接从沙盒的缓存文件中读取需要显示的图片,并将沙盒缓存文件夹(Cache)中保存的图片保存到内存缓存中,这样用户每次滑动tableViewcell重用时直接从内存缓存中读取而不是从沙盒中读取,节约时间.
1>.入口setImageWithUrl:placeHolderImage:options:会把placeHolderImage显示,然后SDWebImageManager根据URL开始处理图片.
2>.进入SDWebImageManager-downloadWithURL:delegate:options:userInfo:交给SDImageCache从缓存查找图片是否已经下载queryDiskCacheForKey:delegate:userInfo:
3>.先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate回调imageCache:didFineImage:forKey:userInfo:到SDWebImageManager.
4>.SDWebImageManagerDelegate回调webImageManager:didFinishWithImage:到UIImageView + WebCache等前端展示图片.
5>.如果内存缓存中没有,生成NSInvocationOperation添加到队列开始从硬盘查找图片是否已经缓存
6>.根据URLKey在硬盘缓存目录下尝试读取图片文件.这一步是在NSOperation进行的操作,所以回主线程进行结果回调notifyDelegate.
7>.如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小 会先清空内存缓存).SDImageCacheDelegate 回调imageCache:didFinishImage: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中内存缓存和硬盘缓存同时保存,写文件到硬盘也在以单独NSInvocationOperation完成,避免拖慢主线程
18>.SDImageCache在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片
19>.SDWI也提供UIButton + WebCache和MKAnnptation + WebCache方便使用
20>.SDWebImagePrefetcher 可以预先下载图片,方便后续使用
如何解决tableView卡,通过设置最大并发数,设置当前页的cell,而不是把所有cell一次性设置完,以及数据图片的三级缓存,直接保存在内存中和沙盒缓存中进行读取,降低网络请求的次数,不仅仅节约用户流量,也会保证tableView滑动的流动性
2.SDWebImage怎么样实现图片的缓存机制的?
图片的缓存,内存缓存,沙盒缓存,操作缓存,以tableViewController为例
每次cell需要显示,都需要重新调用-(UITableViewCell*)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath{}方法
每次调用tableView显示行的数据源方法时,如果需要从网络加载图片,就需要将加载图片这样的耗时操作放在子线程上执行,从网络上下载的图片可以以键值对的形式保存在定义的可变字典中,将每张图片的唯一的路径作为键,将从网络下载下来的图片作为值,保存在内存缓存中,这样每次滑动rtableViewcell 重用时就直接判断内存缓存中有没有需要的图片,如果有就不需要再次下载,在没有出现内存警告或者程序员手动清理内存缓存时,就直接从内存缓存中获取图片
为了每次退回程序,再次进入程序时,不浪费用户的流量,需要将第一次进入程序时加载的图片保存在本地沙盒缓存文件中,在沙盒中保存的图片数据没有被改变之前,下次开启程序就直接从沙盒的缓存文件中读取需要显示的图片,并将沙盒缓存文件夹(Cache)中保存的图片保存到内存缓存中,这样用户每次滑动tableViewcell重用时直接从内存缓存中读取而不是从沙盒中读取,节约时间.
相关文章推荐
- 按右键另存图片只能存BMP
- photoshop去除图片上的水印
- upload上传单张图片
- 图片引发的溢出危机(图)
- C# WinForm控件对透明图片重叠时出现图片不透明的简单解决方法
- C#实现把彩色图片灰度化代码分享
- C#将图片和字节流互相转换并显示到页面上
- C#监控文件夹并自动给图片文件打水印的方法
- 纯CSS实现的当鼠标移上图片添加阴影效果代码
- 如何使用C#从word文档中提取图片
- C#实现打开画图的同时载入图片、最大化显示画图窗体的方法
- C#图片添加水印的实现代码
- 随鼠标移动的图片或文字特效代码
- CSS 图片横向排列实现代码
- C#实现将Email地址转成图片显示的方法
- C#实现图片加相框的方法
- 超级经典一套鼠标控制左右滚动图片带自动翻滚
- 用css实现图片垂直居中的使用技巧
- 一起动手编写Android图片加载框架
- GetChar缓存机制深入剖析