iOS - ImageCache 网络图片缓存

1、ImageCache

  • 使用内存缓存方式:

  • 使用沙盒缓存方式:

  • 使用网络图片第三方库方式:
    • SDWebImage:

      • iOS 中著名的网络图片处理框架
      • 包含的功能:图片下载、图片缓存、下载进度监听、gif 处理等等
      • 用法极其简单,功能十分强大,大大提高了网络图片的处理效率
      • 国内超过 90% 的 iOS 项目都有它的影子
      • 1、图片文件缓存的时间有多长?
        • 1 周
            _maxCacheAge = kDefaultCacheMaxCacheAge;                                    // - (id)initWithNamespace: diskCacheDirectory:
        
            static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7;         // 1 week   SDImageCache.m
      • 2、SDWebImage 的内存缓存是用什么实现的?
        • NSCache
      • 3、SDWebImage 的最大并发数是多少?
        • 是程序固定死了,可以通过属性进行调整!
            _downloadQueue.maxConcurrentOperationCount = 6;                             // SDWebImageDownloader.m   - (id)init
      • 4、网络访问超时时长
        • iOS 开发中,默认的访问时长是 1 分钟,SDWebImage 中是 15 秒。
            _downloadTimeout = 15.0;                                                    // SDWebImageDownloader.m   - (id)init
      • 5、SDWebImage 支持动图吗?GIF
        • 支持
            #import <ImageIO/ImageIO.h>                                                 // UIImage+GIF.m
            [UIImage animatedImageWithImages:images duration:duration];
      • 6、SDWebImage 是如何区分不同格式的图像的
        • 根据图像数据第一个字节来判断的!
            // NSData+ImageContentType.m    + (NSString *)sd_contentTypeForImageData:
        
            PNG:0x89 image/png ,压缩比没有 JPG 高,但是无损压缩,解压缩性能高,苹果推荐的图像格式!
            JPG:0xFF image/jpeg,压缩比最高的一种图片格式,有损压缩!最多使用的场景,照相机!解压缩的性能不好!
            GIF:0x47 image/gif ,序列桢动图,特点:只支持 256 种颜色!最流行的时候在 1998~1999,有专利的!
      • 7、SDWebImage 缓存图片的名称是怎么确定的!
        • md5
        • 如果单纯使用 文件名保存,重名的几率很高!
        • 使用 MD5 的散列函数!对完整的 URL 进行 md5,结果是一个 32 个字符长度的字符串!
      • 8、SDWebImage 的内存警告是如何处理的!
        • 利用通知中心观察
        • UIApplicationDidReceiveMemoryWarningNotification 接收到内存警告的通知
        • 执行 clearMemory 方法,清理内存缓存!
        • UIApplicationWillTerminateNotification 接收到应用程序将要终止通知
        • 执行 cleanDisk 方法,清理磁盘缓存!
        • UIApplicationDidEnterBackgroundNotification 接收到应用程序进入后台通知
        • 执行 backgroundCleanDisk 方法,后台清理磁盘!
        • 通过以上通知监听,能够保证缓存文件的大小始终在控制范围之内!
        • clearDisk 清空磁盘缓存,将所有缓存目录中的文件,全部删除! 实际工作,将缓存目录直接删除,再次创建一个同名空目录!
      • bug:
        • SDWebImage 中,一旦内存警告,清理了内存之后,之后所有的图片都是从沙盒加载的。
        • 原因:NSCache 中一旦调用了 removeAllObjects,就无法给 cache 添加对象。关于 NSCache 的内存管理,交给他自己就行!

2、自定义内存缓存方式

  • Objective-C

    • AppInfoModel.h

          @interface AppInfoModel : NSObject
      
          /// 标题名称
          @property (nonatomic, strong) NSString *name;
      
          /// 下载数量
          @property (nonatomic, strong) NSString *download;
      
          /// 图片地址
          @property (nonatomic, strong) NSString *icon;
      
          /// 声明工厂方法,数据源初始化方法
          + (instancetype)appInfoModelWithDict:(NSDictionary *)dict;
      
          @end
    • AppInfoModel.m
          // 实现工厂方法
          + (instancetype)appInfoModelWithDict:(NSDictionary *)dict {
      
              id obj = [[self alloc] init];
      
              [obj setValuesForKeysWithDictionary:dict];
      
              return obj;
          }
    • AppInfoCell.h
          @interface AppInfoCell : UITableViewCell
      
          @property (nonatomic, weak) IBOutlet UILabel *nameLabel;
          @property (nonatomic, weak) IBOutlet UILabel *downloadLabel;
          @property (nonatomic, weak) IBOutlet UIImageView *iconImageView;
      
          @end
    • ViewController.m
          /// 表格数据源
          @property (nonatomic, strong) NSArray *dataSourceArray;
      
          /// 图片下载队列
          @property (nonatomic, strong) NSOperationQueue *downloadQueue;
      
          /// 下载缓冲池
          @property (nonatomic, strong) NSMutableDictionary *downloadQueueCache;
      
          /// 图片缓冲池
          @property (nonatomic, strong) NSMutableDictionary *imageCache;
      
          /// 图片下载地址黑名单
          @property (nonatomic, retain) NSMutableArray *urlBlackList;
      
          // 懒加载
      
              - (NSArray *)dataSourceArray {
                  if (_dataSourceArray == nil) {
                  NSArray *array = [NSArray arrayWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil]];
      
                  NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:array.count];
                  [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                      [arrayM addObject:[AppInfoModel appInfoModelWithDict:obj]];
                  }];
                      _dataSourceArray = [arrayM copy];
                  }
                  return _dataSourceArray;
              }
      
              - (NSOperationQueue *)downloadQueue {
                  if (_downloadQueue == nil) {
                      _downloadQueue = [[NSOperationQueue alloc] init];
                  }
                  return _downloadQueue;
              }
      
              - (NSMutableDictionary *)downloadQueueCache {
                  if (_downloadQueueCache == nil) {
                      _downloadQueueCache = [[NSMutableDictionary alloc] init];
                  }
                  return _downloadQueueCache;
              }
      
              - (NSMutableDictionary *)imageCache {
                  if (_imageCache == nil) {
                      _imageCache = [[NSMutableDictionary alloc] init];
                  }
                  return _imageCache;
              }
      
              - (NSMutableArray *)urlBlackList {
                  if (_urlBlackList == nil) {
                      _urlBlackList = [[NSMutableArray alloc] init];
                  }
                  return _urlBlackList;
              }
      
          // 表格视图数据源方法
      
              - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                  return self.dataSourceArray.count;
              }
      
              - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      
                  AppInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppCell" forIndexPath:indexPath];
      
                  AppInfoModel *dataModel = self.dataSourceArray[indexPath.row];
      
                  cell.nameLabel.text = dataModel.name;
                  cell.downloadLabel.text = dataModel.download;
      
                  // 判断图片缓存池中是否有相应的图片
                  if (self.imageCache[dataModel.icon] != nil) {                                                           
      
                      // 从缓存池中取出图片显示在 Cell 上
                      cell.iconImageView.image = self.imageCache[dataModel.icon];
                  } else {
      
                      // 从网络异步下载图片
                      [self downloadImageWithIndexPath:indexPath];
                  }
      
                  return cell;
              }
      
              - (void)downloadImageWithIndexPath:(NSIndexPath *)indexPath {
      
                  AppInfoModel *dataModel = self.dataSourceArray[indexPath.row];
      
                  // 判断下载缓冲池中是否存在当前下载操作
                  if (self.downloadQueueCache[dataModel.icon] != nil) {
                      return;
                  }
      
                  // 判断图片地址是否在黑名单中
                  if ([self.urlBlackList containsObject:dataModel.icon]) {
                      return;
                  }
      
                  // 创建异步下载图片操作
                  NSBlockOperation *downloadOperation = [NSBlockOperation blockOperationWithBlock:^{
      
                      UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:dataModel.icon]]];
      
                      // 下载完成从下载缓冲池中删除当前下载操作
                      [self.downloadQueueCache removeObjectForKey:dataModel.icon];
      
                      // 添加黑名单记录
                      if (image == nil && ![self.urlBlackList containsObject:dataModel.icon]) {
                          [self.urlBlackList addObject:dataModel.icon];
                      }
      
                      // 主线程跟新 UI
                      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
      
                          if (image != nil) {
      
                              // 将下载完成的图片保存到图片缓冲池中
                              [self.imageCache setObject:image forKey:dataModel.icon];
      
                              [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                          }
                      }];
                  }];
      
                  // 将当前下载添加到下载缓冲池中
                  [self.downloadQueueCache setObject:downloadOperation forKey:dataModel.icon];
      
                  // 开始异步下载图片
                  [self.downloadQueue addOperation:downloadOperation];
              }
      
          // 内存警告
          /*
              日常上课通常就直接删除,但是在工作后,必须要处理!不处理后果很严重,第一次内存警告如果不处理,就没有第二次的机会了,就直接被闪退了
          */
      
              - (void)didReceiveMemoryWarning {
      
                  [super didReceiveMemoryWarning];
      
                  // 清理缓冲池
                  [self.downloadQueueCache removeAllObjects];
                  [self.imageCache removeAllObjects];
      
                  // 取消下载操作,等用户再滚动表格,调用数据源方法,又能够自动下载
                  [self.downloadQueue cancelAllOperations];
              }
  • Swift
    • AppInfo.swift

          class AppInfo: NSObject {
      
              var name:String!
              var icon:String!
              var download:String!
      
              class func AppInfoWithDict(dict:[String:AnyObject]) -> AnyObject {
                  let obj:AnyObject = self.init()
      
                  obj.setValuesForKeysWithDictionary(dict)
      
                  return obj
              }
      
              required override init() {
                  super.init()
              }
          }
    • AppInfoCell.swift
          class AppInfoCell: UITableViewCell {
      
              @IBOutlet weak var iconView: UIImageView!
              @IBOutlet weak var nameLabel: UILabel!
              @IBOutlet weak var downLabel: UILabel!
          }
    • ViewController.swift
          // 懒加载
      
              // 数据源
              lazy var dataSourceArray:[AnyObject] = {
                  var dataArray:[AnyObject] = Array()
      
                  let array = NSArray(contentsOfURL: NSBundle.mainBundle().URLForResource("apps.plist", withExtension: nil)!)
                  array!.enumerateObjectsUsingBlock { (obj:AnyObject, idx:Int, stop:UnsafeMutablePointer<ObjCBool>) in
                      dataArray.append(AppInfoModel.AppInfoWithDict(obj as! [String : AnyObject]))
                  }
                  return dataArray
              }()
      
              // 下载队列
              lazy var downloadQueue:NSOperationQueue = {
                  var tmp:NSOperationQueue = NSOperationQueue()
                  return tmp
              }()
      
              // 下载缓冲池
              lazy var downloadQueueCache:[String:NSBlockOperation] = {
                  var tmp:[String:NSBlockOperation] = Dictionary()
                  return tmp
              }()
      
              // 图片缓冲池
              lazy var imageCache:[String:UIImage] = {
                  var tmp:[String:UIImage] = Dictionary()
                  return tmp
              }()
      
              // 图片下载地址黑名单
              lazy var urlBlackList:[String] = {
                  var tmp:[String] = Array()
                  return tmp
              }()
      
          // 表格视图数据源方法
      
              override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                  return self.dataSourceArray.count
              }
      
              override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
                  let cell:AppInfoCell = tableView.dequeueReusableCellWithIdentifier("AppCell", forIndexPath: indexPath) as! AppInfoCell
      
                  let dataModel = self.dataSourceArray[indexPath.row] as! AppInfoModel
      
                  cell.nameLabel.text = dataModel.name
                  cell.downLabel.text = dataModel.download
      
                  // 判断图片缓存池中是否有相应的图片
                  if self.imageCache[dataModel.icon] != nil {
      
                      // 从缓存池中取出图片显示在 Cell 上
                      cell.iconView.image = self.imageCache[dataModel.icon]
                  } else {
      
                      // 从网络异步下载图片
                      self.downloadImageWithIndexPath(indexPath)
                  }
                  return cell
              }
      
              func downloadImageWithIndexPath(indexPath:NSIndexPath) {
      
              let dataModel = self.dataSourceArray[indexPath.row] as! AppInfoModel
      
                  // 判断下载缓冲池中是否存在当前下载操作
                  if self.downloadQueueCache[dataModel.icon] != nil {
                      return
                  }
      
                  // 判断图片地址是否在黑名单中
                  if self.urlBlackList.contains(dataModel.icon) {
                      return
                  }
      
                  // 创建异步下载图片操作
                  let downloadOperation = NSBlockOperation {
      
                  let image:UIImage? = UIImage(data: NSData(contentsOfURL: NSURL(string: dataModel.icon)!)!)
      
                  // 下载完成从下载缓冲池中删除当前下载操作
                  self.downloadQueueCache.removeValueForKey(dataModel.icon)
      
                  // 添加黑名单记录
                  if image == nil && !self.urlBlackList.contains(dataModel.icon) {
      
                      self.urlBlackList.append(dataModel.icon)
                  }
      
                  // 主线程跟新 UI
                  NSOperationQueue.mainQueue().addOperationWithBlock({
      
                      if image != nil {
      
                          // 将下载完成的图片保存到图片缓冲池中
                          self.imageCache[dataModel.icon] = image
      
                          self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                      }
                  })
              }
      
                  // 将当前下载添加到下载缓冲池中
                  self.downloadQueueCache[dataModel.icon] = downloadOperation
      
                  // 开始异步下载图片
                  self.downloadQueue.addOperation(downloadOperation)
              }
      
          // 内存警告
      
              override func didReceiveMemoryWarning() {
                  super.didReceiveMemoryWarning()
      
                  self.downloadQueueCache.removeAll()
                  self.imageCache.removeAll()
      
                  self.downloadQueue.cancelAllOperations()
              }

3、自定义沙盒缓存方式

  • Objective-C

    • AppInfoModel.h
    • AppInfoModel.m
    • AppInfoCell.h
      • 与上边一样
    • NSString+BundlePath.h
          ///  拼接缓存目录
          - (NSString *)appendCachePath;
    • NSString+BundlePath.m
          - (NSString *)appendCachePath {
              NSString *dir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
              return [dir stringByAppendingPathComponent:self.lastPathComponent];
          }
    • ViewController.m
          // 懒加载
      
              与上边一样
      
          // 表格视图数据源方法
      
              - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                  return self.dataSourceArray.count;
              }
      
              - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      
                  AppInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppCell" forIndexPath:indexPath];
      
                  AppInfoModel *dataModel = self.dataSourceArray[indexPath.row];
      
                  cell.nameLabel.text = dataModel.name;
                  cell.downloadLabel.text = dataModel.download;
      
                  // 判断图片缓存池中是否有相应的图片
                  if (self.imageCache[dataModel.icon] != nil) {
      
                      // 从缓存池中取出图片显示在 Cell 上
                      cell.iconImageView.image = self.imageCache[dataModel.icon];
                  } else {
      
                      // 从沙盒加载图片
                      UIImage *image = [UIImage imageWithContentsOfFile:[dataModel.icon appendCachePath]];
      
                      if (image != nil) {
      
                          cell.iconImageView.image = image;
                          self.imageCache[dataModel.icon] = image;
      
                      } else {
      
                          // 从网络异步下载图片
                          [self downloadImageWithIndexPath:indexPath];
                      }
                  }
      
                  return cell;
              }
      
              - (void)downloadImageWithIndexPath:(NSIndexPath *)indexPath {
      
                  AppInfoModel *dataModel = self.dataSourceArray[indexPath.row];
      
                  // 判断下载缓冲池中是否存在当前下载操作
                  if (self.downloadQueueCache[dataModel.icon] != nil) {
                      return;
                  }
      
                  // 判断图片地址是否在黑名单中
                  if ([self.urlBlackList containsObject:dataModel.icon]) {                                                
      
                      return;
                  }
      
                  // 创建异步下载图片操作
                  NSBlockOperation *downloadOperation = [NSBlockOperation blockOperationWithBlock:^{
      
                      NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:dataModel.icon]];
                      UIImage *image = [UIImage imageWithData:imageData];
      
                      // 下载完成从下载缓冲池中删除当前下载操作
                      [self.downloadQueueCache removeObjectForKey:dataModel.icon];
      
                      // 添加黑名单记录
                      if (image == nil && ![self.urlBlackList containsObject:dataModel.icon]) {
                          [self.urlBlackList addObject:dataModel.icon];
                      }
      
                      if (image != nil) {
      
                          // 将图像写入沙盒
                          [imageData writeToFile:[dataModel.icon appendCachePath] atomically:YES];
                      }
      
                      // 主线程跟新 UI
                      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
      
                          if (image != nil) {
      
                              // 将下载完成的图片保存到图片缓冲池中
                              [self.imageCache setObject:image forKey:dataModel.icon];
      
                              [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                          }
                      }];
                  }];
      
                  // 将当前下载添加到下载缓冲池中
                  [self.downloadQueueCache setObject:downloadOperation forKey:dataModel.icon];
      
                  // 开始异步下载图片
                  [self.downloadQueue addOperation:downloadOperation];
              }
      
          // 内存警告
      
              与上边一样
  • Swift
    • AppInfo.swift
    • AppInfoCell.swift
      • 与上边一样
    • String+BundlePath.swift
          public func appendCachePath() -> String? {
              let dir:String? = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true).last
              if (dir != nil) {
                  return dir! + "/" + (self as NSString).lastPathComponent
              } else {
                  return nil
              }
          }
    • ViewController.swift
          // 懒加载
      
              与上边一样
      
          // 表格视图数据源方法
      
              override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                  return self.dataSourceArray.count
              }
      
              override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
                  let cell:AppInfoCell = tableView.dequeueReusableCellWithIdentifier("AppCell", forIndexPath: indexPath) as! AppInfoCell
      
                  let dataModel = self.dataSourceArray[indexPath.row] as! AppInfoModel
      
                  cell.nameLabel.text = dataModel.name
                  cell.downLabel.text = dataModel.download
      
                  // 判断图片缓存池中是否有相应的图片
                  if self.imageCache[dataModel.icon] != nil {
      
                      // 从缓存池中取出图片显示在 Cell 上
                      cell.iconView.image = self.imageCache[dataModel.icon]
      
                  } else {
      
                      // 从沙盒加载图片
                      let image = UIImage(contentsOfFile: dataModel.icon.appendCachePath()!)
      
                      if (image != nil) {
      
                          cell.iconView.image = image
                          self.imageCache[dataModel.icon] = image
      
                      } else {
      
                          // 从网络异步下载图片
                          self.downloadImageWithIndexPath(indexPath)
                      }
                  }
      
                  return cell
              }
      
              func downloadImageWithIndexPath(indexPath:NSIndexPath) {
      
                  let dataModel = self.dataSourceArray[indexPath.row] as! AppInfoModel
      
                  // 判断下载缓冲池中是否存在当前下载操作
                  if self.downloadQueueCache[dataModel.icon] != nil {
      
                      return
                  }
      
                  // 判断图片地址是否在黑名单中
                  if self.urlBlackList.contains(dataModel.icon) {
      
                      return
                  }
      
                  // 创建异步下载图片操作
                  let downloadOperation = NSBlockOperation {
      
                  let imageData:NSData? = NSData(contentsOfURL: NSURL(string: dataModel.icon)!)
      
                  let image:UIImage? = UIImage(data: imageData!)
      
                      // 下载完成从下载缓冲池中删除当前下载操作
                      self.downloadQueueCache.removeValueForKey(dataModel.icon)
      
                      // 添加黑名单记录
                      if image == nil && !self.urlBlackList.contains(dataModel.icon) {
      
                          self.urlBlackList.append(dataModel.icon)
                      }
      
                      if image != nil {
      
                          // 将图像写入沙盒
                          imageData!.writeToFile(dataModel.icon.appendCachePath()!, atomically: true)
      
                          print(dataModel.icon.appendCachePath()!)
                      }
      
                      // 主线程跟新 UI
                      NSOperationQueue.mainQueue().addOperationWithBlock({
      
                          if image != nil {
      
                              // 将下载完成的图片保存到图片缓冲池中
                              self.imageCache[dataModel.icon] = image                                                             
      
                              self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                          }
                      })
                  }
      
                  // 将当前下载添加到下载缓冲池中
                  self.downloadQueueCache[dataModel.icon] = downloadOperation
      
                  // 开始异步下载图片
                  self.downloadQueue.addOperation(downloadOperation)
              }
      
          // 内存警告
      
              与上边一样

4、仿 SDWebImage 缓存方式

  • Objective-C

    • AppInfoModel.h

          @interface AppInfoModel : NSObject
      
          /// 标题名称
          @property (nonatomic, strong) NSString *name;
      
          /// 下载数量
          @property (nonatomic, strong) NSString *download;
      
          /// 图片地址
          @property (nonatomic, strong) NSString *icon;
      
          /// 从 Plist 加载 AppInfo
          + (NSArray *)loadPList;
      
          @end
    • AppInfoModel.m
          + (NSArray *)loadPList {
      
              NSArray *array = [NSArray arrayWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil]];
      
              NSMutableArray *plist = [NSMutableArray arrayWithCapacity:array.count];
              [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
      
                  id model = [[self alloc] init];
                  [model setValuesForKeysWithDictionary:obj];
      
                  [plist addObject:model];
              }];
      
              return plist;
          }
    • AppInfoCell.h
          @interface AppInfoCell : UITableViewCell
      
          @property (nonatomic, weak) IBOutlet UILabel *nameLabel;
          @property (nonatomic, weak) IBOutlet UILabel *downloadLabel;
          @property (nonatomic, weak) IBOutlet UIImageView *iconImageView;
      
          @end
    • NSString+BundlePath.h
          ///  拼接缓存目录
          - (NSString *)appendCachePath;
    • NSString+BundlePath.m
          - (NSString *)appendCachePath {
              NSString *dir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
              return [dir stringByAppendingPathComponent:self.lastPathComponent];
          }
    • WebImageOperation.h
          @interface WebImageOperation : NSOperation
      
          ///  实例化 web 图像操作
          + (instancetype)webImageOperationWithURLString:(NSString *)urlString completion:(void (^)(UIImage *image))completion;
      
          @end
    • WebImageOperation.m
          /// 下载图片的 URL
          @property (nonatomic, copy) NSString *urlStr;
      
          /// 下载完成的回调
          @property (nonatomic, copy) void (^completion) (UIImage *image);
      
          + (instancetype)webImageOperationWithURLString:(NSString *)urlString completion:(void (^)(UIImage *))completion {
      
              WebImageOperation *imageOperation = [[self alloc] init];
      
              imageOperation.urlStr= urlString;
              imageOperation.completion = completion;
      
              return imageOperation;
          }
      
          // 操作加入队列后会自动执行该方法
          - (void)main {
              @autoreleasepool {
      
                  if (self.isCancelled) return;
      
                  NSURL *url = [NSURL URLWithString:self.urlStr];
                  NSData *data = [NSData dataWithContentsOfURL:url];
      
                  if (self.isCancelled) return;
      
                  if (data != nil) {
                      [data writeToFile:self.urlStr.appendCachePath atomically:YES];
                  }
      
                  if (self.isCancelled) return;
      
                  if (self.completion && data != nil) {
      
                      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
      
                          self.completion([UIImage imageWithData:data]);
                      }];
                  }
              }
          }
    • WebImageManager.h
          //  负责所有网络图像的下载操作以及缓存管理!
          @interface WebImageManager : NSObject
      
          ///  全局单例访问入口
          + (instancetype)sharedManager;
      
          ///  下载网络图像
          - (void)downloadImage:(NSString *)urlString completion:(void (^) (UIImage *image))completion;
      
          ///  取消 urlString 对应的下载操作
          - (void)cancelDownload:(NSString *)urlString;
      
          @end
    • WebImageManager.m
          /// 下载队列
          @property (nonatomic, strong) NSOperationQueue *downloadQueue;
      
          /// 下载操作缓冲池
          @property (nonatomic, strong) NSMutableDictionary *downloadQueueCache;
      
          /// 图片缓冲池
          @property (nonatomic, strong) NSMutableDictionary *imageCache;
      
          // 下载管理器
      
              // 实例化下载管理器
              + (instancetype)sharedManager {
      
                  static id instance;
      
                  static dispatch_once_t onceToken;
                  dispatch_once(&onceToken, ^{
                      instance = [[self alloc] init];
                  });
                  return instance;
              }
      
          // 下载操作
      
              - (void)downloadImage:(NSString *)urlString completion:(void (^)(UIImage *))completion {
      
                  // 判断缓存中是否存在图像
                  if ([self checkCacheWithURLString:urlString]) {
      
                      if (completion != nil) {
      
                          // 直接回调,传递给调用方图像
                          completion(self.imageCache[urlString]);
                      }
      
                      return;
                  }
      
                  // 判断缓冲池中是否存在下载操作
                  if (self.downloadQueueCache[urlString] != nil) {
      
                      return;
                  }
      
                  WebImageOperation *downloadOperation = [WebImageOperation webImageOperationWithURLString:urlString
                                                                                            completion:^(UIImage *image) {
      
                      // 下载完成从操作缓冲池中移除操作
                      [self.downloadQueueCache removeObjectForKey:urlString];
      
                      // 下载完成添加到图片缓冲池中
                      [self.imageCache setObject:image forKey:urlString];
      
                      if (completion != nil) {
                          completion(image);
                      }
                  }];
      
                  // 将操作添加到缓冲池
                  [self.downloadQueueCache setObject:downloadOperation forKey:urlString];
      
                  // 将操作添加到队列
                  [self.downloadQueue addOperation:downloadOperation];
              }
      
              // 取消 urlString 对应的下载操作
              - (void)cancelDownload:(NSString *)urlString {
      
                  // 从缓冲池拿到下载操作
                  WebImageOperation *downloadOperation = self.downloadQueueCache[urlString];
      
                  if (downloadOperation != nil) {
      
                      // 取消操作
                      [downloadOperation cancel];
      
                      // 从缓冲池中删除操作
                      [self.downloadQueueCache removeObjectForKey:urlString];
                  }
              }
      
              // 判断缓存中是否存在图像
              - (BOOL)checkCacheWithURLString:(NSString *)urlString {
      
                  // 判断图片缓冲池中是否存在图像
                  if (self.imageCache[urlString] != nil) {
                      return YES;
                  }
      
                  UIImage *image = [UIImage imageWithContentsOfFile:[urlString appendCachePath]];
      
                  // 判断沙盒中是否存在图像
                  if (image != nil) {
      
                      [self.imageCache setObject:image forKey:urlString];
      
                      return YES;
                  }
      
                  return NO;
              }
      
          // 懒加载
      
              - (NSOperationQueue *)downloadQueue {
                  if (_downloadQueue == nil) {
                      _downloadQueue = [[NSOperationQueue alloc] init];
                  }
                  return _downloadQueue;
              }
      
              - (NSMutableDictionary *)downloadQueueCache {
                  if (_downloadQueueCache == nil) {
                      _downloadQueueCache = [[NSMutableDictionary alloc] init];
                  }
                  return _downloadQueueCache;
              }
      
              - (NSMutableDictionary *)imageCache {
                  if (_imageCache == nil) {
                      _imageCache = [[NSMutableDictionary alloc] init];
                  }
                  return _imageCache;
              }
    • UIImageView+WebImageView.h
          @interface UIImageView (WebImageView)
      
          /// 设置 Web 图像 URL,自动加载图像
          - (void)setWebImageWithURL:(NSString *)urlString;
      
          @end
    • UIImageView+WebImageView.m
          #import <objc/runtime.h>
      
          // 下载图片的 url
          @property (nonatomic, copy) NSString *urlStr;
      
          - (void)setWebImageWithURL:(NSString *)urlString {
      
              // 屏蔽快速滑动重复添加下载
              if ([self.urlStr isEqualToString:urlString]) {
      
                  return;
              }
      
              // 暂停之前的操作
              if (self.urlStr != nil && ![self.urlStr isEqualToString:urlString]) {
      
                  [[WebImageManager sharedManager] cancelDownload:self.urlStr];
      
                  // 如果 ImageView 之前有图像-清空图像
                  self.image = nil;
              }
      
              // 记录新的 url
              self.urlStr = urlString;
      
              __weak typeof(self) weakSelf = self;
      
              // 下载网络图片
              [[WebImageManager sharedManager] downloadImage:self.urlStr completion:^(UIImage *image) {
                  weakSelf.image = image;
              }];
          }
      
          // 向分类添加属性
      
          // 运行时的关联对象,动态添加属性
          const void *URLStrKey = "URLStrKey";
      
          - (void)setUrlStr:(NSString *)urlString {
              objc_setAssociatedObject(self, URLStrKey, urlString, OBJC_ASSOCIATION_COPY_NONATOMIC);
          }
      
          - (NSString *)urlStr {
              return objc_getAssociatedObject(self, URLStrKey);
          }
    • ViewController.m
          /// 表格数据源
          @property (nonatomic, strong) NSArray *dataSourceArray;
      
          // 懒加载
      
              - (NSArray *)dataSourceArray {
                  if (_dataSourceArray == nil) {
                      _dataSourceArray = [AppInfoModel loadPList];
                  }
                  return _dataSourceArray;
              }
      
          // 表格视图数据源方法
      
              - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                  return self.dataSourceArray.count;
              }
      
              - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      
                  AppInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppCell" forIndexPath:indexPath];
      
                  AppInfoModel *dataModel = self.dataSourceArray[indexPath.row];
      
                  cell.nameLabel.text = dataModel.name;
                  cell.downloadLabel.text = dataModel.download;
      
                  [cell.iconImageView setWebImageWithURL:dataModel.icon];
      
                  return cell;
              }
  • Swift
    • AppInfoModel.swift

          class AppInfoModel: NSObject
      
          var name:String!
          var icon:String!
          var download:String!
      
          class func loadPList() -> [AnyObject] {
              let array = NSArray(contentsOfURL: NSBundle.mainBundle().URLForResource("apps.plist", withExtension: nil)!)
      
              var plist:[AnyObject] = Array()
              array!.enumerateObjectsUsingBlock { (obj:AnyObject, idx:Int, stop:UnsafeMutablePointer<ObjCBool>) in
      
                  let model:AnyObject = self.init()
      
                  model.setValuesForKeysWithDictionary(obj as! [String : AnyObject])
      
                  plist.append(model)
              }
              return plist
          }
      
          class func AppInfoWithDict(dict:[String:AnyObject]) -> AnyObject {
              let obj:AnyObject = self.init()
      
              obj.setValuesForKeysWithDictionary(dict)
      
              return obj
          }
      
          required override init() {
              super.init()
          }
    • AppInfoCell.swift
          @IBOutlet weak var iconView: UIImageView!
          @IBOutlet weak var nameLabel: UILabel!
          @IBOutlet weak var downLabel: UILabel!
    • String+BundlePath.swift
          ///  拼接缓存目录
          public func appendCachePath() -> String? {
              let dir:String? = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true).last
              if (dir != nil) {
                  return dir! + "/" + (self as NSString).lastPathComponent
              } else {
                  return nil
              }
          }
    • WebImageOperation.swift
          class WebImageOperation: NSOperation
      
          /// 下载图片的 URL
          var urlStr:String!
      
          /// 下载完成的回调
          var completion:((image:UIImage) -> Void)!
      
              class func webImageOperationWithURLString(urlString:String, completion:((image:UIImage) -> Void)) -> WebImageOperation {
      
              let imageOperation:WebImageOperation = WebImageOperation()
      
              imageOperation.urlStr = urlString
              imageOperation.completion = completion
      
              return imageOperation
          }
      
          // 操作加入队列后会自动执行该方法
          override func main() {
      
              if self.cancelled == true {
                  return
              }
      
              let url:NSURL = NSURL(string: self.urlStr)!
              let data:NSData? = NSData(contentsOfURL: url)
      
              if self.cancelled == true {
                  return
              }
      
              if data != nil {
      
                  data?.writeToFile(self.urlStr.appendCachePath()!, atomically: true)
              }
      
              if self.cancelled == true {
                  return
              }
      
              if (self.completion != nil) && (data != nil) {
      
                  NSOperationQueue.mainQueue().addOperationWithBlock({
      
                      self.completion(image: UIImage(data: data!)!)
                  })
              }
          }
    • WebImageManager.swift
          // 负责所有网络图像的下载操作以及缓存管理!
          class WebImageManager: NSObject
      
          // 下载队列
          lazy var downloadQueue:NSOperationQueue = {
      
              var tmp:NSOperationQueue = NSOperationQueue()
              return tmp
          }()
      
          // 下载缓冲池
          lazy var downloadQueueCache:[String:WebImageOperation] = {
      
              var tmp:[String:WebImageOperation] = Dictionary()
              return tmp
          }()
      
          // 图片缓冲池
          lazy var imageCache:[String:UIImage] = {
      
              var tmp:[String:UIImage] = Dictionary()
              return tmp
          }()
      
          // 下载管理器
      
              static let sharedManager = WebImageManager()
              private override init() {}
      
          // 下载操作
      
              func downloadImage(urlString:String, completion:((image:UIImage) -> Void)?) {
      
                  // 判断缓存中是否存在图像
                  if self.checkCacheWithURLString(urlString) == true {
      
                      if completion != nil {
      
                          // 直接回调,传递给调用方图像
                          completion!(image: self.imageCache[urlString]!)
                      }
      
                      return
                  }
      
                  // 判断缓冲池中是否存在下载操作
                  if self.downloadQueueCache[urlString] != nil {
      
                      print("玩命下载中...稍安勿躁!")
      
                      return
                  }
      
                  let downloadOperation:WebImageOperation = WebImageOperation.webImageOperationWithURLString(urlString) { (image) in
      
                  // 下载完成从操作缓冲池中移除操作
                  self.downloadQueueCache.removeValueForKey(urlString)
      
                      // 下载完成添加到图片缓冲池中
                      self.imageCache[urlString] = image
      
                      if (completion != nil) {
                          completion!(image: image);
                      }
                  }
      
                  // 将操作添加到缓冲池
                  self.downloadQueueCache[urlString] = downloadOperation
      
                  // 将操作添加到队列
                  self.downloadQueue.addOperation(downloadOperation)
              }
      
              // 取消 urlString 对应的下载操作
              func cancelDownload(urlString:String) {
      
                  // 从缓冲池拿到下载操作
                  let downloadOperation:WebImageOperation? = self.downloadQueueCache[urlString]
      
                  if downloadOperation != nil {
      
                      print("取消下载操作")
      
                      // 取消操作
                      downloadOperation!.cancel()
      
                      // 从缓冲池中删除操作
                      self.downloadQueueCache.removeValueForKey(urlString)
                  }
              }
      
              // 判断缓存中是否存在图像
              func checkCacheWithURLString(urlString:String) -> Bool {
      
                  // 判断图片缓冲池中是否存在图像
                  if self.imageCache[urlString] != nil {
      
                      print("从内存中加载...")
      
                      return true
                  }
      
                  let image:UIImage? = UIImage(contentsOfFile: urlString.appendCachePath()!)
      
                  // 判断沙盒中是否存在图像
                  if image != nil {
      
                      print("从沙盒中加载...")
      
                      self.imageCache[urlString] = image
      
                      return true
                  }
      
                  return false
              }
    • UIImageView+WebImageView.h
          @interface UIImageView (WebImageView)
      
          /// 设置 Web 图像 URL,自动加载图像
          - (void)setWebImageWithURL:(NSString *)urlString;
      
          @end
    • UIImageView+WebImageView.m
          #import <objc/runtime.h>
          #import "SwiftImageCache-Swift.h"
      
          // 下载图片的 url
          @property (nonatomic, copy) NSString *urlStr;
      
          - (void)setWebImageWithURL:(NSString *)urlString {
      
              // 屏蔽快速滑动重复添加下载
              if ([self.urlStr isEqualToString:urlString]) {
      
                  return;
              }
      
              // 暂停之前的操作
              if (self.urlStr != nil && ![self.urlStr isEqualToString:urlString]) {
      
                  [[WebImageManager sharedManager] cancelDownload:self.urlStr];
      
                  // 如果 ImageView 之前有图像-清空图像
                  self.image = nil;
              }
      
              // 记录新的 url
              self.urlStr = urlString;
      
              __weak typeof(self) weakSelf = self;
      
              // 下载网络图片
              [[WebImageManager sharedManager] downloadImage:self.urlStr completion:^(UIImage *image) {
                  weakSelf.image = image;
              }];
          }
      
          // 向分类添加属性
      
          // 运行时的关联对象,动态添加属性
          const void *URLStrKey = "URLStrKey";
      
          - (void)setUrlStr:(NSString *)urlString {
              objc_setAssociatedObject(self, URLStrKey, urlString, OBJC_ASSOCIATION_COPY_NONATOMIC);
          }
      
          - (NSString *)urlStr {
              return objc_getAssociatedObject(self, URLStrKey);
          }
    • SwiftImageCache-Bridging-Header.h
          #import "UIImageView+WebImageView.h"
    • ViewController.swift
          // 懒加载
      
              lazy var dataSourceArray:[AnyObject] = {
                  var tmp:[AnyObject] = AppInfoModel.loadPList()
                  return tmp
              }()
      
          // 表格视图数据源方法
      
              override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                  return self.dataSourceArray.count
              }
      
              override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
                  let cell:AppInfoCell = tableView.dequeueReusableCellWithIdentifier("AppCell", forIndexPath: indexPath) as! AppInfoCell
      
                  let dataModel = self.dataSourceArray[indexPath.row] as! AppInfoModel
      
                  cell.nameLabel.text = dataModel.name
                  cell.downLabel.text = dataModel.download
      
                  cell.iconView.setWebImageWithURL(dataModel.icon)
      
                  return cell
              }

5、SDWebImage 缓存方式

  • Github 网址:https://github.com/rs/SDWebImage
  • SDWebImage 使用 ARC
  • Objective-C
        // 添加第三方库文件
        SDWebImage
    
        // 包含头文件
        #import "UIImageView+WebCache.h"
    • AppInfoModel.h

          @interface AppInfoModel : NSObject
      
          /// 标题名称
          @property (nonatomic, strong) NSString *name;
      
          /// 下载数量
          @property (nonatomic, strong) NSString *download;
      
          /// 图片地址
          @property (nonatomic, strong) NSString *icon;
      
          /// 从 Plist 加载 AppInfo
          + (NSArray *)loadPList;
      
          @end
    • AppInfoModel.m
          + (NSArray *)loadPList {
      
              NSArray *array = [NSArray arrayWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil]];
      
              NSMutableArray *plist = [NSMutableArray arrayWithCapacity:array.count];
              [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
      
                  id model = [[self alloc] init];
                  [model setValuesForKeysWithDictionary:obj];
      
                  [plist addObject:model];
              }];
      
              return plist;
          }
    • AppInfoCell.h
          @interface AppInfoCell : UITableViewCell
      
          @property (nonatomic, weak) IBOutlet UILabel *nameLabel;
          @property (nonatomic, weak) IBOutlet UILabel *downloadLabel;
          @property (nonatomic, weak) IBOutlet UIImageView *iconImageView;
      
          @end
    • ViewController.m
          /// 表格数据源
          @property (nonatomic, strong) NSArray *dataSourceArray;
      
          // 懒加载
      
              - (NSArray *)dataSourceArray {
                  if (_dataSourceArray == nil) {
                      _dataSourceArray = [AppInfoModel loadPList];
                  }
                  return _dataSourceArray;
              }
      
          // 表格视图数据源方法
      
              - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                  return self.dataSourceArray.count;
              }
      
              - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      
                  AppInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppCell" forIndexPath:indexPath];
      
                  AppInfoModel *dataModel = self.dataSourceArray[indexPath.row];
      
                  cell.nameLabel.text = dataModel.name;
                  cell.downloadLabel.text = dataModel.download;
      
                  [cell.iconImageView sd_setImageWithURL:[NSURL URLWithString:dataModel.icon]];
      
                  return cell;
              }
  • Swift
        // 添加第三方库文件
        SDWebImage
    
        // 创建桥接头文件,如
        SwiftImageCache-Bridging-Header.h
    
        // 在桥接头文件中添加头文件
        #import "UIImageView+WebCache.h"
    • AppInfoModel.swift

          class AppInfoModel: NSObject    
      
          var name:String!
          var icon:String!
          var download:String!
      
          class func loadPList() -> [AnyObject] {
              let array = NSArray(contentsOfURL: NSBundle.mainBundle().URLForResource("apps.plist", withExtension: nil)!)
      
              var plist:[AnyObject] = Array()
              array!.enumerateObjectsUsingBlock { (obj:AnyObject, idx:Int, stop:UnsafeMutablePointer<ObjCBool>) in
      
                  let model:AnyObject = self.init()
      
                  model.setValuesForKeysWithDictionary(obj as! [String : AnyObject])
      
                  plist.append(model)
              }
              return plist
          }
      
          class func AppInfoWithDict(dict:[String:AnyObject]) -> AnyObject {
              let obj:AnyObject = self.init()
      
              obj.setValuesForKeysWithDictionary(dict)
      
              return obj
          }
      
          required override init() {
              super.init()
          }
    • AppInfoCell.swift
          class AppInfoCell: UITableViewCell  
      
          @IBOutlet weak var iconView: UIImageView!
          @IBOutlet weak var nameLabel: UILabel!
          @IBOutlet weak var downLabel: UILabel!
    • ViewController.swift
          // 懒加载
      
              lazy var dataSourceArray:[AnyObject] = {
                  var tmp:[AnyObject] = AppInfoModel.loadPList()
                  return tmp
              }()
      
          // 表格视图数据源方法
      
              override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                  return self.dataSourceArray.count
              }
      
              override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
                  let cell:AppInfoCell = tableView.dequeueReusableCellWithIdentifier("AppCell", forIndexPath: indexPath) as! AppInfoCell
      
                  let dataModel = self.dataSourceArray[indexPath.row] as! AppInfoModel
      
                  cell.nameLabel.text = dataModel.name
                  cell.downLabel.text = dataModel.download
      
                  // 设置图片
                  cell.iconView.sd_setImageWithURL(NSURL(string: dataModel.icon))
      
                  return cell
              }
时间: 2024-07-28 19:54:41

iOS - ImageCache 网络图片缓存的相关文章

ios做数据缓存后,显示数据的逻辑是怎样的?

问题描述 ios做数据缓存后,显示数据的逻辑是怎样的? ios做数据缓存后,显示数据的逻辑是怎样的?因为有上拉加载更多,和下拉刷新,求思路 解决方案 iOS数据缓存iOS开发数据缓存玩转iOS开发 - 数据缓存 解决方案二: 1.获取服务器数据后,可以写入本地文件中,需要用到的时候再去读取就可以了: 2.分页的话类似的: 解决方案三: 每次加载页面都可以先从缓存里面读取,读不到再网络获取

android-Android 网络图片缓存到本地,并优先加载本地缓存图片

问题描述 Android 网络图片缓存到本地,并优先加载本地缓存图片 用volley加载网络图片到listview,但是imageloder貌似只缓存到内存,这要每次重新打开都要在网络上重新下载,求解怎么实现网络图片缓存到本地,并优先加载本地缓存图片,最好有详细的文章解释或者DEMO啊,谢谢大神了~ 解决方案 你自己把它保存到本地文件,比如根据url保存,这样访问同样的地址就会从本地读取 解决方案二: 把你本地文件先读到内存,把这个缓存传给volley 解决方案三: setDiskcache(t

iOS 数据库离线缓存思路和网络层封装

一直想总结一下关于iOS的离线数据缓存的方面的问题,然后最近也简单的对AFN进行了再次封装,所有想把这两个结合起来写一下.数据展示型的页面做离线缓存可以有更好的用户体验,用户在离线环境下仍然可以获取一些数据,这里的数据缓存首选肯定是SQLite,轻量级,对数据的存储读取相对于其他几种方式有优势,这里对AFN的封装没有涉及太多业务逻辑层面的需求,主要还是对一些方法再次封装方便使用,解除项目对第三方的耦合性,能够简单的快速的更换底层使用的网络请求代码.这篇主要写离线缓存思路,对AFN的封装只做简单的

iOS AFNetworking 数据缓存(3)

AFNetWorking 在IOS开发中是一个经常会用的第三方开源库,其最好处是维护及时,源码开源.  常用GET与POST请求方法: POST请求:  ? 1 2 3 4 5 6 7 8 9 //初始化一个请求对象  AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];   NSString * url = @"你的请求地址";   //dic 为参数字典  [manager

iOS - OC NSCache 缓存

前言 NSCache 是苹果提供的一个专门用来做缓存的类,当内存 "不足" 或超过限制的时候,会自动清理缓存,使用时可以指定缓存的数量和成本.用法与 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,都使用它来管理缓存. - (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g; 设置对象并指定 "成本",成本可以自行指定 例子:缓存图片 1

iOS AFNetworking 数据缓存

How Does Caching Work in AFNetworking? : AFImageCache & NSUrlCache Explained FEB 20TH, 2014 If you are an iOS developer using  Mattt Thompson's 'delightful networking framework' AFNetworking (and if you aren't, what are you waiting for?), perhaps you

iOS开发缓存机制之—内存缓存机制

在IOS应用程序开发中,为了减少与服务端的交互次数,加快用户的响应速度,一般都会在iOS设备中加一个缓存的机制. 这篇文章将介绍一下如何在iOS设备中进行缓存,本文先介绍一下将内容缓存到内存中,下一篇文章就介绍一下在iOS磁盘上缓存内容.   使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,是程序高效的运行.有时候我们需要将远程web服务器获取的数据缓存起来,减少对同一个url多次请求. 内存缓存我们可以使用sdk中的NSURLCache类.NSURLRequest需要一个缓存参数来说

iOS网络编程之六——数据缓存类NSURLCache使用解析

iOS网络编程之六--数据缓存类NSURLCache使用解析 一.引言         在前面博客中,介绍了NSURLRequest请求类的相关使用方法,其中有介绍关于请求返回数据的缓存策略,实际上,iOS中具体缓存操作的管理是由NSURLCache类来实现的.NSURLRequest类介绍的博客地址如下: iOS中NSURLRequest相关使用:http://my.oschina.net/u/2340880/blog/620225. 二.NSURLCache中方法与属性 ? 1 2 3 4

iOS开发网络篇—数据缓存

iOS开发网络篇-数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以下问题 (1)用户流量的浪费 (2)程序响应速度不够快 解决上面的问题,一般考虑对数据进行缓存. 二.缓存 为了提高程序的响应速度,可以考虑使用缓存(内存缓存\硬盘缓存) 第一次请求数据时,内存缓存中没有数据,硬盘缓存中没有数据. 缓存数据的过程 当服务器返回数据时,需要做以下步骤 (1)使用服务器