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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。