当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS多线程实现多图下载功能

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

重生空间守则,聂绀弩刑事档案,凉宫哈尔滨

本文实例为大家分享了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 

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网