iOS处理高并发量的数据请求和数据集合的对应关系
一、处理高并发请求的核心代码如下:
// 创建信号量dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);// 创建全局并行dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, queue, ^{// 请求[self httpRequest];dispatch_semaphore_signal(semaphore);});dispatch_group_notify(group, queue, ^{// 请求对应信号等待dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);});
分析:
首先创建并行队列,创建队列组,将队列和需要处理的网络请求分别添加到组中,当组中所有队列处理完事件后调用dispatch_group_notify,我们需要在里边处理事件。由于队列在处理网络请求时将”发送完一个请求”作为事件完成的标记(此时还未获得网络请求返回数据),所以在这里需要用信号量进行控制,在执行dispatch_group_notify前发起信号等待(三次信号等待,分别对应每个队列的信号通知),在每个队列获取到网络请求返回数据时发出信号通知。这样就能完成需求中的要求。
如果需求中改为:同时存在A,B,C三个任务,要求ABC依次进行处理,当上一个完成时再进行下一个任务,当三个任务都完成时再处理事件。这时只需要将队列改为串行队列即可(不在需要信号量控制)。
二、处理高并发请求完成后数据集合的一一对应关系
假如for遍历发送HTTP并发请求时,由于服务端响应数据的时间不同,会造成请求到的数据集合与发请求的顺序非一一对应,思路如下,创建可变字典
NSMutableDictionary
建立起请求与数据集合的对应关系。然后遍历字典,按key
的顺序重新整理数据集合NSMutableDictionary *twoCategoryData = [NSMutableDictionary dictionary];[_bigDict setObject:twoSmallDataArr forKey:[NSString stringWithFormat:@"%ld",index]];if (_bigDict.count == _oneCategoryData.count) {for (int i=0; i<_oneCategoryData.count; i++) {NSArray *arr = [_bigDict objectForKey:[NSString stringWithFormat:@"%d",i]];[_twoCategoryData addObject:arr];}
项目中源码参考
// 获取一级分类data - (void)getCategory {[HTTPMANGER getFirstLevelCategoryListSuccessedBlock:^(NSDictionary *resultDict) {NSLog(@"resultDict:%@",resultDict);if (DATAINFO_SUCCESS) {// 一级分类数组_oneCategoryData = [NSMutableArray array];_twoCategoryData = [NSMutableArray array];_bigDict = [NSMutableDictionary dictionary];for (NSDictionary *dic in DATA) {CategoryModel *categoryModel = [CategoryModel initJson:dic];[_oneCategoryData addObject:categoryModel];// 创建信号量dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);// 创建全局并行dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, queue, ^{NSUInteger index = [DATA indexOfObject:dic];[self getTwoClassData:dic index:index];dispatch_semaphore_signal(semaphore);});dispatch_group_notify(group, queue, ^{// 请求对应信号等待dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);});}}} failedBolck:^(NSError *error) {NSLog(@"error:%@",error);}]; } // 获取二级分类data - (void)getTwoClassData:(NSDictionary *)dic index:(NSUInteger)index {[HTTPMANGER getSecondLevelCategoryListWithCategoryId:dic[@"CATEGORY_ID"] successedBlock:^(NSDictionary *resultDict) {NSLog(@"resultDict:%@",resultDict);NSMutableArray *twoSmallDataArr = [NSMutableArray array];NSMutableDictionary *twoCategoryData = [NSMutableDictionary dictionary];for (NSDictionary *smalldic in DATA) {CategoryModel *smallModel = [CategoryModel initJson:smalldic];[twoCategoryData setObject:smallModel.CATEGORY_NAME forKey:@"name"];[twoCategoryData setObject:smallModel.CATEGORY_ID forKey:@"type"];[twoCategoryData setObject:smallModel.SUPER_CATEGORY_ID forKey:@"super"];[twoSmallDataArr addObject:twoCategoryData];}//[_twoCategoryData addObject:twoSmallDataArr];[_bigDict setObject:twoSmallDataArr forKey:[NSString stringWithFormat:@"%ld",index]];if (_bigDict.count == _oneCategoryData.count) {for (int i=0; i<_oneCategoryData.count; i++) {NSArray *arr = [_bigDict objectForKey:[NSString stringWithFormat:@"%d",i]];[_twoCategoryData addObject:arr];}[self initSearchBar];}} failedBolck:^(NSError *error) {NSLog(@"error:%@",error);}]; }
相关文章:
Top 10 Mistakes Java Developers Make(转)
文章列出了Java开发者最常犯的是个错误。 1.将数组转换为ArrayList 为了将数组转换为ArrayList,开发者经常会这样做: ?1List<String> list Arrays.asList(arr);Arrays.asList()会返回一个ArrayList,但这个ArrayList是Arrays的私有静态…

Python3中迭代器介绍
Python中一个可迭代对象(iterable object)是一个实现了__iter__方法的对象,它应该返回一个迭代器对象(iterator object)。迭代器是一个实现__next__方法的对象,它应该返回它的可迭代对象的下一个元素,并在没有可用元素时触发StopIteration异常…
30+博士、100+硕士整理的超全深度强化学习资源清单
作者 | Deep-RL来源 | 深度强化学习实验室(ID:Deep-RL)今天为大家推荐一个开源、开发的 Github 好项目《A Guide for Deep Reinforcement Learning》。这个项目联合了Deep Reinforcement Learning领域的30位博士,100位硕士共同完成…

Java访问者模式
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受…

GNU/Linux平台上正则表达式的简单使用
友情提醒:本博文涉及的内容中涉及到的系统实践操作在Centos6.5上实现,GNU/Linux简称为linux,GNU/grep简称为grep,GNU/sed简称为sed,GNU/gawk简称为awk。-------------------------------------------------楔子------------------…

Linux下addr2line命令用法
Linux下addr2line命令用于将程序指令地址转换为所对应的函数名、以及函数所在的源文件名和行号。当含有调试信息(-g)的执行程序出现crash时(core dumped),可使用addr2line命令快速定位出错的位置。 如果无法确定文件名或函数名,addr2line将在它们的位置打…

JavaMVC 模式
MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。 Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。View࿰…
从概念到技术,打通「中台」的任督二脉,别再说不知道中台是什么
2019 年,「中台」这个词火了!随着阿里等头部互联网企业搭建和推动中台业务,让越来越多的企业关注中台,纷纷提出「中台战略」,帮助企业自身加速实现数字化转型。不少企业还在观望「中台」:1、我的企业里需要…

php中序列化与反序列化
http://www.cnblogs.com/A-Song/archive/2011/12/13/2285619.html 转自:http://qing.weibo.com/tag/unserialize 把复杂的数据类型压缩到一个字符串中 serialize() 把变量和它们的值编码成文本形式unserialize() 恢复原先变量eg:$stooges array(Moe,Larry,Curly);$…

Python3中生成器介绍
生成器(generator):一个返回生成器迭代器的函数。它看起来像一个普通函数,除了它包含用于生成一系列可在for循环中使用的值的yield表达式或者可以使用next函数一次检索一个值。 在Python中,使用了yield的函数被称为生成器。跟普通函数不同的是…
数学学渣必备!拍照上传,分步求解,微软解题神器拯救你
整理 | Jane出品 | AI科技大本营(ID:rgznai100)在学好数学这条路上,很多同志前赴后继「死伤无数」,即便大家不断的寻求「场外救援」,可最终都逃不过一个字:难!两个字:真难…

Java业务代表模式
业务代表模式(Business Delegate Pattern)用于对表示层和业务层解耦。它基本上是用来减少通信或对表示层代码中的业务层代码的远程查询功能。在业务层中我们有以下实体。 客户端(Client) - 表示层代码可以是 JSP、servlet 或 UI j…

在wamp环境下面安装Zend Optimizer的方法
我是用WAMP来做PHP的服务器,进行本机测试和开发PHP项目。 wamp环境是刚刚安装的。由于这个项目的代码是zend加密的,运行时候都是乱码,需要安装一个Zend Optimizer配置。 首先下载一个Zend Optimizer软件。 1、进入安装界面后,按NE…

libuvc介绍及简单使用
libuvc是一个用于USB视频设备的跨平台库,构建在libusb之上,编译libuvc时需要依赖libusb。libuvc的License为BSD,最新发布版本为0.0.6,源码地址: https://github.com/libuvc/libuvc libuvc支持在非windows系统上直接编译࿰…
AI又被彩虹吹!网易被预言为“下一个百度”?
人工智能到底有多火?近日国内首份《BAT人工智能领域人才发展报告》新鲜出炉,此次报告是针对国内人工智能领域的人才争夺情况进行了梳理。并把研究对象锁定在BAT三大巨头的身上。来源:《BAT人工智能领域人才发展报告》其中得出最为核心的结论&…

Java组合实体模式
组合实体模式(Composite Entity Pattern)用在 EJB 持久化机制中。一个组合实体是一个 EJB 实体 bean,代表了对象的图解。当更新一个组合实体时,内部依赖对象 beans 会自动更新,因为它们是由 EJB 实体 bean 管理的。以下…

JAVA的StringBuffer类
StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。 所以在实际使用时,如果…
程序员请收好:10个非常有用的Visual Studio Code插件
作者 | Daan译者 | Elle出品 | CSDN(ID:CSDNnews)【导读】一个插件列表,可以让你的程序员生活变得轻松许多。无论你是经验丰富的开发人员还是刚刚开始第一份工作的初级开发人员,你都会想让自己的开发工作尽可能轻松一点…

Python3中装饰器介绍
Python中的装饰器(decorator)是一个接受另一个函数作为参数的函数。装饰器通常会修改或增强它接受的函数并返回修改后的函数。这意味着当你调用一个装饰函数时,你会得到一个与基本定义相比可能有一些额外特性的函数。Python中的函数可以用作或作为参数传递。 Python…

Java数据访问对象模式
数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来。以下是数据访问对象模式的参与者。 数据访问对象接口(Data Access Object Interface) - 该接口定义了在一…

hdoj 5199 Gunner map
Gunner Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid5199 Description Long long ago, there is a gunner whose name is Jack. He likes to go hunting very much. One day he go to the grove. There are n birds and n tr…

Python3中上下文管理器介绍
在任何编程语言中,文件操作或数据库连接等资源的使用都很常见。但这些资源供应有限。因此,主要问题在于确保在使用后释放这些资源。如果不释放它们,则会导致资源泄漏,并可能导致系统变慢或崩溃。如果用户有一个自动设置和拆卸资源…
LatentFusion:华盛顿大学与英伟达联合提出6D姿态估计新方法
作者 | Keunhong Park、Arsalan Mousavian、Yu Xiang、Dieter Fox 译者 | 刘畅 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100) 【导读】在本文中,华盛顿大学和英伟达联合提出了一种新的用于未见过目标 6D姿态估计的框架。作…

Java前端控制器模式
前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种…

提供第三种代码生成方式——通过自定义BuildProvider为ASP.NET提供代码生成
2019独角兽企业重金招聘Python工程师标准>>> 之前写了一些关于代码生成的文章,提供了两种不同方式的代码生成解决方案,即CodeDOMCustom Tool和T4。对于ASP.NET应用,你还有第三种选择——自定义BuildProvider。[文中涉及的源代码从…

Java拦截过滤器模式
拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,然后把请…

1200亿次日均位置服务响应、20亿公里日均轨迹里程,百度地图发布新一代人工智能地图生态全景
12月10日,百度地图首次公布了“新一代人工智能地图”生态全景。目前,百度地图日均位置服务请求次数突破1200亿次,日均轨迹里程20亿公里,注册开发者数量达180万,服务超过50万个移动应用。 百度地图事业部总经理李莹称&…

Python3中global/nonlocal用法
全局变量(global variable)是那些未在任何函数内部定义并且具有全局作用域的变量,而局部变量(local variable)是那些在函数内部定义并且其作用域仅限于该函数的变量。换句话说,我们可以说局部变量只能在初始化它的函数内部访问,而全局变量在整…

客户端动态调用WCF服务中的方法
首先要写一个执行动态调用的方法:在里面实现反射调用。 public static object ExecuteMethod<T>(string pUrl,string pMethodName, params object[] pParams) { EndpointAddress address new EndpointAddress(pUrl); Binding bindinginstance null; NetTcpB…

Python3中闭包介绍
Python3中的闭包(closure)是一个函数对象,它记住封闭作用域(enclosing function)中的值,即使它们不存在于内存中。它是一个将函数与环境一起存储的记录。由于闭包用作回调函数,因此它们提供了某种数据隐藏,这有助于我们减少使用全…