在一次面试一个ios职位时遭遇到这样一个问题,当一个tableview中许多cell中的uiimageview请求相同地址的图片时,如何保证对于同一url只进行一次网络请求,从而避免没必要的网络请求以提高运行效率。
对于这个问题,如果对于同一url请求,当任何一次请求没完成保存本地缓存时,其他请求先去查看本地缓存,这个时候是找不到的,所以也会发送网络请求,这样确实存在效率问题。 自己设计的图片请求如何解决这个问题,对于面试时的紧张局势首先想到的是使用字典以url为key,每次网络请求之前查找key,如果没有则请求网络下载,如果有则不请求,这样有一个问题急待解决,就是没有请求如何设置image并且在合适的时机设置image呢?想到的笨方法当然是当第一个请求完成并设置了本地缓存时通知另外的uiimage去再掉一次 sd_setImageWithURL 这个时候会走缓存获取效率非常高,这个方法还得继承uiimageview,在心的uiimageview中响应通知,显然这种方式很难得到面试官的认可,并不是他想要的答案,十分沮丧。回头翻阅了SDWbimage是如何实现的呢
SDWebimageDownloder中有很好的实现
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock
这个方法是实际请求网络的实现
其中调用
- (void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock andCompletedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL *)url createCallback:(SDWebImageNoParamsBlock)createCallback
来实现相同url是否发起网络请求的判断
看一下代码比较清晰,用barrier保证顺序
dispatch_barrier_sync(self.barrierQueue, ^{