欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS多线程实现多图下载功能

程序员文章站 2023-12-16 08:25:10
本文实例为大家分享了ios多线程实现多图下载功能的具体代码,供大家参考,具体内容如下 一.模型文件代码如下 // xmgapp.h #import...

本文实例为大家分享了ios多线程实现多图下载功能的具体代码,供大家参考,具体内容如下

一.模型文件代码如下

// xmgapp.h 
 
#import <foundation/foundation.h> 
 
@interface xmgapp : nsobject 
 
/** app的名称 */ 
@property (nonatomic, strong) nsstring *name; 
/** app的图片的url地址 */ 
@property (nonatomic, strong) nsstring *icon; 
/** app的下载量 */ 
@property (nonatomic, strong) nsstring *download; 
 
+(instancetype)appwithdict:(nsdictionary *)dict; 
@end 
// xmgapp.m 
 
#import "xmgapp.h" 
 
@implementation xmgapp 
 
+(instancetype)appwithdict:(nsdictionary *)dict 
{ 
  xmgapp *appm = [[xmgapp alloc]init]; 
  //kvc 
  [appm setvaluesforkeyswithdictionary:dict]; 
   
  return appm; 
} 
@end 

控制器.m代码如下:

// viewcontroller.m 
 
#import "viewcontroller.h" 
#import "xmgapp.h" 
 
@interface viewcontroller () 
/** tableview的数据源 */ 
@property (nonatomic, strong) nsarray *apps; 
/** 内存缓存 */ 
@property (nonatomic, strong) nsmutabledictionary *images; 
/** 队列 */ 
@property (nonatomic, strong) nsoperationqueue *queue; 
/** 操作缓存 */ 
@property (nonatomic, strong) nsmutabledictionary *operations; 
@end 
 
@implementation viewcontroller 
 
#pragma mark ---------------------- 
#pragma mark lazy loading 
-(nsoperationqueue *)queue 
{ 
  if (_queue == nil) { 
    _queue = [[nsoperationqueue alloc]init]; 
    //设置最大并发数 
    _queue.maxconcurrentoperationcount = 5; 
  } 
  return _queue; 
} 
-(nsmutabledictionary *)images 
{ 
  if (_images == nil) { 
    _images = [nsmutabledictionary dictionary]; 
  } 
  return _images; 
} 
-(nsarray *)apps 
{ 
  if (_apps == nil) { 
     
    //字典数组 
    nsarray *arraym = [nsarray arraywithcontentsoffile:[[nsbundle mainbundle]pathforresource:@"apps.plist" oftype:nil]]; 
     
    //字典数组---->模型数组 
    nsmutablearray *arrm = [nsmutablearray array]; 
    for (nsdictionary *dict in arraym) { 
      [arrm addobject:[xmgapp appwithdict:dict]]; 
    } 
    _apps = arrm; 
  } 
  return _apps; 
} 
 
-(nsmutabledictionary *)operations 
{ 
  if (_operations == nil) { 
    _operations = [nsmutabledictionary dictionary]; 
  } 
  return _operations; 
} 
 
#pragma mark ---------------------- 
#pragma mark uitableviewdatasource 
-(nsinteger)numberofsectionsintableview:(uitableview *)tableview 
{ 
  return 1; 
} 
 
-(nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section 
{ 
  return self.apps.count; 
} 
 
-(uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath 
{ 
  static nsstring *id = @"app"; 
   
  //1.创建cell 
  uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:id]; 
   
  //2.设置cell的数据 
  //2.1 拿到该行cell对应的数据 
  xmgapp *appm = self.apps[indexpath.row]; 
   
  //2.2 设置标题 
  cell.textlabel.text = appm.name; 
   
  //2.3 设置子标题 
  cell.detailtextlabel.text = appm.download; 
   
  //2.4 设置图标 
   
  //先去查看内存缓存中该图片时候已经存在,如果存在那么久直接拿来用,否则去检查磁盘缓存 
  //如果有磁盘缓存,那么保存一份到内存,设置图片,否则就直接下载 
  //1)没有下载过 
  //2)重新打开程序 
   
  uiimage *image = [self.images objectforkey:appm.icon]; 
  if (image) { 
    cell.imageview.image = image; 
    nslog(@"%zd处的图片使用了内存缓存中的图片",indexpath.row) ; 
  }else 
  { 
    //保存图片到沙盒缓存 
    nsstring *caches = [nssearchpathfordirectoriesindomains(nscachesdirectory, nsuserdomainmask, yes) lastobject]; 
    //获得图片的名称,不能包含/ 
    nsstring *filename = [appm.icon lastpathcomponent]; 
    //拼接图片的全路径 
    nsstring *fullpath = [caches stringbyappendingpathcomponent:filename]; 
     
     
    //检查磁盘缓存 
    nsdata *imagedata = [nsdata datawithcontentsoffile:fullpath]; 
    //废除 
    imagedata = nil; 
     
    if (imagedata) { 
      uiimage *image = [uiimage imagewithdata:imagedata]; 
      cell.imageview.image = image; 
       
      nslog(@"%zd处的图片使用了磁盘缓存中的图片",indexpath.row) ; 
      //把图片保存到内存缓存 
      [self.images setobject:image forkey:appm.icon]; 
       
//      nslog(@"%@",fullpath); 
    }else 
    { 
      //检查该图片时候正在下载,如果是那么久什么都捕捉,否则再添加下载任务 
      nsblockoperation *download = [self.operations objectforkey:appm.icon]; 
      if (download) { 
         
      }else 
      { 
         
        //先清空cell原来的图片 
        cell.imageview.image = [uiimage imagenamed:@"snip20160221_306"]; 
         
        download = [nsblockoperation blockoperationwithblock:^{ 
          nsurl *url = [nsurl urlwithstring:appm.icon]; 
          nsdata *imagedata = [nsdata datawithcontentsofurl:url]; 
          uiimage *image = [uiimage imagewithdata:imagedata]; 
           
           nslog(@"%zd--下载---",indexpath.row); 
           
          //容错处理 
          if (image == nil) { 
            [self.operations removeobjectforkey:appm.icon]; 
            return ; 
          } 
          //演示网速慢的情况 
          //[nsthread sleepfortimeinterval:3.0]; 
         
          //把图片保存到内存缓存 
          [self.images setobject:image forkey:appm.icon]; 
           
          //nslog(@"download---%@",[nsthread currentthread]); 
          //线程间通信 
          [[nsoperationqueue mainqueue] addoperationwithblock:^{ 
             
            //cell.imageview.image = image; 
            //刷新一行 
            [self.tableview reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationleft]; 
            //nslog(@"ui---%@",[nsthread currentthread]); 
          }]; 
           
           
          //写数据到沙盒 
          [imagedata writetofile:fullpath atomically:yes]; 
           
          //移除图片的下载操作 
          [self.operations removeobjectforkey:appm.icon]; 
           
        }]; 
         
        //添加操作到操作缓存中 
        [self.operations setobject:download forkey:appm.icon]; 
         
        //添加操作到队列中 
        [self.queue addoperation:download]; 
      } 
       
    } 
  } 
   
  //3.返回cell 
  return cell; 
} 
 
-(void)didreceivememorywarning 
{ 
  [self.images removeallobjects]; 
   
  //取消队列中所有的操作 
  [self.queue cancelalloperations]; 
} 
 
//1.ui很不流畅 --- > 开子线程下载图片 
//2.图片重复下载 ---> 先把之前已经下载的图片保存起来(字典) 
//内存缓存--->磁盘缓存 
 
//3.图片不会刷新--->刷新某行 
//4.图片重复下载(图片下载需要时间,当图片还未完全下载之前,又要重新显示该图片) 
//5.数据错乱 ---设置占位图片 
 
/* 
 documents:会备份,不允许 
 libray 
  preferences:偏好设置 保存账号 
  caches:缓存文件 
 tmp:临时路径(随时会被删除) 
 */ 
 
@end 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: