ios afnetworking 回调要不要写vuex dispatch 回调

最近把其他书籍都放下了,主要是在研究GCD。如果是为了工作,以我以前所学的GCD、NSOperation等知识已经足够用了,但学习并不仅仅知识满足于用它,要知其然、并且知其所以然,这样才可以不断的提高自身技术水平。
本文主要参考/60749/grand-central-dispatch-in-depth-part-1 和 《iOS与OS X 多线程和内存管理》,以及其他一些杂七杂八的书籍或者博客。
GCD已经面世很久了,基于GCD面向对象的多线程技术NSOperation也出现很久了,但并不是所有人都明了GCD主要内容,并发一直很棘手(虽然AFNetworking框架在一定程度上避免了很多时候我们在程序内赤裸裸的写多线程代码,但我想任何一个有想法的程序员都会深入理解并发编程,并将之掌握的),它们就像一组尖锐的棱角戳进 Objective-C 的平滑世界。
在这里,我将会四个篇幅来梳理自己所知、所理解的GCD。
第一、二篇主要是解释GCD是什么、能做什么,会提供我所编写好的一些代码片段,必要时,会有demo。
第三篇和第三篇主要是学习一些高级GCD提供的高级函数,如果时间充足,我会尽量以文字+代码+demo展示。
如果你对GCD和Block(代码块)完全陌生,请先看这篇文章:/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial & & & &《iOS上GCD和多线程的入门教程》
进程:也就是一个正在运行的应用程序。
线程:进程中的某一条完整的执行路径。一个进程可以有多个线程,至少有一个线程,即主线程。在iOS开发中,所有涉及UI界面的,必须在主线程中更新。
什么是GCD?
苹果官方给出的解释:GCD是异步执行任务的技术之一。一般将应用程序中记述的线程管理代码在系统集中实现,开发者只需要定义想执行的任务并追加到
适当的Dispatch Queue中,GCD就可以生成必要的线程并计划执行任务。
它具有以下优点:
GCD可以将花费时间极其长的任务放到后台线程,可以改善应用的响应性能
GCD 提供一个易于使用的并发模型而不仅仅只是锁和线程,以帮助我们避开并发陷阱
GCD 具有在常见模式(例如单例)上用更高性能的原语优化你的代码的潜在能力(后面会提供一个单例的medo)
如下面的代码片段:
dispatch_queue_t queue = dispatch_queue_create("cn.chutong.www", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
放一些极其耗时间的任务在此执行
dispatch_async(dispatch_get_main_queue(), ^{
耗时任务完成,拿到资源,更新UI
更新UI只可以在主线程中更新
&我创建了一个并行队列queue,并异步执行耗时操作,当耗时操作执行完毕,我拿到其中的资源回到主线程来更新相应的UI,在这个Block代码块之外,主线程并不会被耗时任务所堵塞,可以流畅的处理其他事情。
GCD的一些术语
要理解 GCD ,要先熟悉与线程和并发相关的几个概念。
串行(Serial)与 &并发(Concurrent)
任务串行,意味着在同一时间,有且只有一个任务被执行,即一个任务执行完毕之后再执行下一个任务。
任务并发,意味着在同一时间,有多个任务被执行。
同步(Synchronous)与 &异步 (Asynchronous)
同步,意味着在当前线程中执行任务,不具备开启新的线程的能力。
异步,在新的线程中执行任务,具备开启新的线程的能力。
在 GCD 中,这些术语描述当一个函数相对于另一个任务完成,此任务是该函数要求 GCD 执行的。一个同步函数只在完成了它预定的任务后才返回。
一个异步函数,刚好相反,会立即返回,预定的任务会完成但不会等它完成。因此,一个异步函数不会阻塞当前线程去执行下一个函数。
临界区(Critical Section)
就是一段代码不能被并发执行,也就是,两个线程不能同时执行这段代码。这很常见,因为代码去操作一个共享资源,例如一个变量若能被并发进程访问,那么它很可能会变质(它的值不再可信)。
死锁(Deadlock)
停止等待事情的线程会导致多个线程相互维持等待,即死锁。
两个(有时更多)东西&&在大多数情况下,是线程&&所谓的死锁是指它们都卡住了,并等待对方完成或执行其它操作。第一个不能完成是因为它在等待第二个的完成。但第二个也不能完成,因为它在等待第一个的完成。
代码片段:
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"111111");
NSLog(@"222222");
执行上面的代码,你会发现没有任何打印,这个时候就是发生了死锁,我们禁止在主队列(iOS开发中,主队列是串行队列)中,在同步使用主队列执行任务,同理,禁止在同一个同步串行队列中,再使用该串行队列同步的执行任务,因为这样会造成死锁。
代码片段:
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_queue_create("cn.chutong.www", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"111111");
dispatch_sync(queue, ^{
NSLog(@"22222");
NSLog(@"3333333");
NSLog(@"");
&会发现,只是打印了一次,然后就造成了死锁。
线程安全(Thread Safe)
线程安全的代码能在多线程或并发任务中被安全的调用,而不会导致任何问题(数据损坏,崩溃,等)。线程不安全的代码在某个时刻只能在一个上下文中运行。一个线程安全代码的例子是 NSDictionary 。你可以在同一时间在多个线程中使用它而不会有问题。另一方面,NSMutableDictionary 就不是线程安全的,应该保证一次只能有一个线程访问它。
上下文切换(Context Switch)
一个上下文切换指当你在单个进程里切换执行不同的线程时存储与恢复执行状态的过程。这个过程在编写多任务应用时很普遍,但会带来一些额外的开销。
并发与并行
并行要求并发,但并发不能保证并行,就计算机操作系统来说,开启线程是很耗性能的,也就是说,事实上,在某次并行处理任务中,开启的线程是有上限的,如果上限为2,即每次开启的新线程为2,那么是有可能出现并发却不并行的情况。
并发代码的不同部分可以&同步&执行。然而,该怎样发生或是否发生都取决于系统。多核设备通过并行来同时执行多个线程;然而,为了使单核设备也能实现这一点,它们必须先运行一个线程,执行一个上下文切换,然后运行另一个线程或进程。这通常发生地足够快以致给我们并发执行地错觉,如下图所示:&
队列(Queue)
&苹果官方对GCD的说明:开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。
&这句话的源码如下:
dispatch_async(queue, ^{
想要执行的任务
&该源码使用Block语法&定义想执行的任务&,通过dispatch_async函数&追加&赋值在变量queue的"Dispatch Queue中"。仅仅是这样,就可以使得指定的Block在另一线程中执行。
GCD 提供有 dispatch queue 来处理代码块,这些队列管理你提供给 GCD 的任务并用 FIFO (先进先出)顺序执行这些任务。这就保证了第一个被添加到队列里的任务会是队列中第一个开始的任务,而第二个被添加的任务将第二个开始,如此直到队列的终点。
Dispatch Queue是什么呢?是执行处理的等待队列,程序员通过dispatch_async等API,在Block语法中记述想要执行的处理,并将其追加到Dispatch Queue中。Dispatch Queue按照追加的顺序进行处理。
所有的调度队列(dispatch queue)自身都是线程安全的,你能从多个线程并行的访问它们。 GCD 的优点是显而易见的,即当你了解了调度队列如何为你自己代码的不同部分提供线程安全。关于这一点的关键是选择正确类型的调度队列和正确的调度函数来提交你的工作。
另外,在执行处理时,存在本文前面提到的两种Dispatch Queue,一种是等待现在执行中处理的Serial Dispatch Queue,另一种是Concurrent Dispatch Queue。
串行队列(Serial Dispatch Queue )&
这些任务的执行时机受到 GCD 的控制;唯一能确保的事情是 GCD 一次只执行一个任务,并且按照我们添加到队列的顺序来执行。
如下代码,当调用serialPrintNumber方法时:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) dispatch_queue_t serialQ
@property (nonatomic, strong) dispatch_queue_t concurrentQ
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.serialQueue = dispatch_queue_create("cn.chutong.www", DISPATCH_QUEUE_SERIAL);
self.concurrentQueue = dispatch_queue_create("cn.chutong.www", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i & 100; i++) {
[self serialPrintNumber:i];
异步串行队列
- (void)serialPrintNumber:(int)number
dispatch_async(self.serialQueue, ^{
NSLog(@"%d
%@",number, [NSThread currentThread]);
异步并行队列
- (void)concurrentPrintNumber:(int)number
dispatch_async(self.concurrentQueue, ^{
NSLog(@"%d
%@",number, [NSThread currentThread]);
&可以看到这样的打印:
&开辟了一个新的子线程,任务是按顺序执行的。先进先出顺序执行的。因为要等待前一个任务处理结束,即同一时间,只能处理一个任务,才可以开始处理下一任务。
并发队列(Concurrent Dispatch Queue)
在并发队列中的任务能得到的保证是它们会按照被添加的顺序开始执行,但这就是全部的保证了。任务可能以任意顺序完成,你不会知道何时开始运行下一个任务,或者任意时刻有多少 Block 在运行。再说一遍,这完全取决于 GCD
代码片段:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) dispatch_queue_t serialQ
@property (nonatomic, strong) dispatch_queue_t concurrentQ
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.serialQueue = dispatch_queue_create("cn.chutong.www", DISPATCH_QUEUE_SERIAL);
self.concurrentQueue = dispatch_queue_create("cn.chutong.www", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i & 100; i++) {
[self concurrentPrintNumber:i];
异步串行队列
- (void)serialPrintNumber:(int)number
dispatch_async(self.serialQueue, ^{
NSLog(@"%d
%@",number, [NSThread currentThread]);
异步并行队列
- (void)concurrentPrintNumber:(int)number
dispatch_async(self.concurrentQueue, ^{
NSLog(@"%d
%@",number, [NSThread currentThread]);
可以看到,不再是顺序执行任务,开了多个线程。至此,我们可以清楚的知道,所谓&并行执行&,就是使用多个线程同时处理多个任务,因为完成任务所需要消耗的时间不同,所以完成任务的最终时间不同。
Serial Dispatch Queue 与 Concurrent Dispatch Queue 和线程之间的关系,如下图:
阅读(...) 评论()2015年4月 移动开发大版内专家分月排行榜第二
2015年5月 移动开发大版内专家分月排行榜第三2015年3月 移动开发大版内专家分月排行榜第三2014年10月 移动开发大版内专家分月排行榜第三
2015年5月 移动开发大版内专家分月排行榜第一2015年4月 移动开发大版内专家分月排行榜第一2014年9月 移动开发大版内专家分月排行榜第一
2015年3月 移动开发大版内专家分月排行榜第二2014年8月 移动开发大版内专家分月排行榜第二
2015年5月 移动开发大版内专家分月排行榜第一2015年4月 移动开发大版内专家分月排行榜第一2014年9月 移动开发大版内专家分月排行榜第一
2015年3月 移动开发大版内专家分月排行榜第二2014年8月 移动开发大版内专家分月排行榜第二
2015年5月 移动开发大版内专家分月排行榜第一2015年4月 移动开发大版内专家分月排行榜第一2014年9月 移动开发大版内专家分月排行榜第一
2015年3月 移动开发大版内专家分月排行榜第二2014年8月 移动开发大版内专家分月排行榜第二
2015年5月 移动开发大版内专家分月排行榜第一2015年4月 移动开发大版内专家分月排行榜第一2014年9月 移动开发大版内专家分月排行榜第一
2015年3月 移动开发大版内专家分月排行榜第二2014年8月 移动开发大版内专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。主题 : AFNetworking请求数据,为什么第一遍总是不往里进。
级别: 新手上路
可可豆: 74 CB
威望: 74 点
在线时间: 13(时)
发自: Web Page
来源于&&分类
AFNetworking请求数据,为什么第一遍总是不往里进。&&&
- (NSMutableArray *)createRequestWithUrlString:(NSString *)string {    _dataArr = [[NSMutableArray alloc]init];    AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];    manger.responseSerializer = [AFHTTPResponseSerializer serializer];  
[manger GET:string parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {        if (operation.responseData) {            NSDictionary *result = [NSJSONSerialization JSONObjectWithData:operation.responseData options:NSJSONReadingMutableContainers error:nil];            NSArray *resultArr = [result objectForKey:@&news&];            for (NSDictionary *dict in resultArr) {                TopModel *model = [[TopModel alloc]init];                [model assinWithDict:dict];                [_dataArr addObject:model];            }            [self reloadData];        }    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {        NSLog(@&error = %@&,error);    }];    return _dataA}请求数据总是直接跳出来,返回的内容为空,但是在里边打断点的话发现还是执行里面了。到底是什么个状况,求大神帮忙解答。
级别: 圣骑士
UID: 405567
可可豆: 1389 CB
威望: 1370 点
在线时间: 1108(时)
发自: Web Page
这是个异步请求&& 主线程优先&&&&return _dataA&&放在Success里面试试&&这样应该可以&& 异步请求&&会先return掉得&& ,放在success里 就不一样了
级别: 新手上路
可可豆: 74 CB
威望: 74 点
在线时间: 13(时)
发自: Web Page
回 1楼(408月少) 的帖子
是把 return _dataArr放到 success里面么?&&不行啊,放进去就报错了,
图片:屏幕快照
上午11.41.59.png
级别: 圣骑士
UID: 405567
可可豆: 1389 CB
威望: 1370 点
在线时间: 1108(时)
发自: Web Page
写成Void类型的函数&& 不要返回值&&直接刷新UI&&&& 因为在Success里面给_dataArr已经赋值了&& 然后刷新&&应该没问题
级别: 新手上路
可可豆: 74 CB
威望: 74 点
在线时间: 13(时)
发自: Web Page
回 3楼(408月少) 的帖子
我要创建多个tableView,所以要多次下载下载数据,所以这里是我继承系统的tableView自定义的tableVIew,我把下载写到这里面了,外面调用的时候要用到这个这个返回的数组作为数据源。&&大神,是不是我这样写逻辑有问题么?
级别: 侠客
UID: 301626
可可豆: 2511 CB
威望: 1589 点
在线时间: 184(时)
发自: Web Page
用block回调形式搞吧,我之前也是纠结了一上午才上网找到解决方案
级别: 侠客
UID: 330065
可可豆: 414 CB
威望: 383 点
在线时间: 220(时)
发自: Web Page
这种异步加载方法一般都没返回值的。都是通过block去回调的。。
级别: 新手上路
UID: 391990
可可豆: 103 CB
威望: 94 点
在线时间: 142(时)
发自: Web Page
block回调直接有了吧&&不需要返回值把
级别: 侠客
UID: 417688
可可豆: 530 CB
威望: 411 点
在线时间: 134(时)
发自: Web Page
1)关于为何_dataArr返回为空的解释;当你使用AFNetworking发起get请求后,请求成功的回调success与请求失败的回调failure会在子线程里执行,而你的return _dataArr会在主线程里执行,这种Black体的回调机制类似于代理(异步机制),虽然你把[_dataArr addObject:model];写在了return _dataArr前,你以为写在前面的就会先执行(同一个线程里会是那样),实际上这里这两句代码分属于不同的线程。在这里,先执行return _dataAr,所以返回的结果为空。2)对Black体的解释success: void (^)(AFHTTPRequestOperation *operation, id responseObject)failure&&&&:void (^)(AFHTTPRequestOperation *operation, NSError *error)这两个Block体的返回类型都为空,所以当你返回数组时,你把success: void (^)(AFHTTPRequestOperation *operation, id responseObject)变成了success: NSMutableArray * (^)(AFHTTPRequestOperation *operation, id responseObject),所以错误。3)Black体只可以访问并修改全局变量,全局静态变量,局部静态变量,对象的成员变量,对象的属性,__black修饰的局部变量,其余的均只可访问,不能修改。兄弟有时间看看Black的详解吧!另外妈的,敲了一片没保存一下就没了,这是第二遍。尼玛,为何我的问题没人回答!!!
随风起舞......
级别: 新手上路
UID: 428455
可可豆: 24 CB
威望: 23 点
在线时间: 528(时)
发自: Web Page
回 6楼(hcydmc) 的帖子
求怎么用block回调啊
关注本帖(如果有新回复会站内信通知您)
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 关注CVP公众号
扫一扫 浏览移动版iOS AFNetworking使用技巧与问题(持续更新) - 简书
iOS AFNetworking使用技巧与问题(持续更新)
1.很多初学者,在每处用到网络请求的地方会直接?拿afn实例去请求?,从而带来了后续难以维护代码的问题
[[AFHTTPSessionManager manager] POST:nil parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
} failure:^(NSURLSessionDataTask *task, NSError *error) {
思考:如果afn不更新了,后续出现重大?bug适配问题,从而导致每处?用到afn的地方都要修改,请问怎么办?
答案:呵呵,只能一个个修改了!有人会说,怎么可能不更新,很多人用着呢,怕什么。那假设其他第三方也同样出现类型的问题呢?所以是不是应该有方法或某种思想去解决呢?
解决方法:写个网络基类HRHttpBase,提供两个方法:GET 与 POST,外面请求时,直接调用这两个方法,万一afn出了问题,只要修改这两个方法即可,从而减轻后续维护成本!这种做法?同样适用于其他的第三方库, 这也是一种开发思想。
HRHttpBase.h
HRHttpBase.m
假设业务复杂的话,如登录,涉及到第三方登录之类的,有比较多的网络请求,可以专门抽一个网络请求类要处理:
HRhttpLogin.h
HRhttpLogin.m
2.?用到CocoaPods,但更改了afn代码问题
这是缺少text/html解析格式,请求网络时,只要添加上就行了,很多人在网上找到设置的地方(如下图)。但他忘了,项目用CocoaPods管理第三方库的,如果项目上线之前,同事更新了CocoaPods那么之前写的代码就没了!
解决办法:通过AFHTTPSessionManager实例找到AFHTTPResponseSerializer 对象,然后看有没提供对应的方法或属性可设置该格式。
像类似的网络请求header和user-agent都应该在自己的代码里设置!
3.返回字符串而并非是json或xml格式,怎么解析?
开发中确实是存在?奇葩的需求,还有可能返回一堆html格式的String,要截取Sting里的某个key。对于处理不了的格式,afn有可能error回调。
用AFHTTPSessionManager,我没找到未解析的字符(知道的朋友可以告诉我,谢谢)。最后还是用了AFHTTPRequestOperationManager
operation.responseString即为未格式化的字符
Paste_Image.png
ps:如果朋友们还有些奇怪的问题,可以回复我,一起解决!
文章同步到微信公众号:hans_iOS 有疑问可以在公众号里询问!
iOS开发工程师
文章同步到微信公众号:hans_iOS
有疑问可以在公众号里询问!
用到的组件1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SDWebImage多个缩略图缓存组件 UICKeyChainStore存放用户账号密码组件 Reachability监测网络状态 DateTools友好...
下边都学会就大神了: 声明:都是网上搜集的,能标明出处的都标了.别只搜集而不看,与君共勉.. 先看完整项目完整App@HackerNews-React-Native用 React Native 完成的 HackerNews 客户端。WeChat实现类似微信朋友圈或者QQ空间...
发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注
09:45字数 61697阅读 3316评论 2喜欢 85 用到的组件 1、通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FM...
用到的组件1、通过CocoaPods安装项目名称项目信息AFNetworking网络请求组件FMDB本地数据库组件SDWebImage多个缩略图缓存组件UICKeyChainStore存放用户账号密码组件Reachability监测网络状态DateTools友好化时间MBP...
AFNetworking网络请求组件SDWebImage多个缩略图缓存组件FMDB本地数据库组件UICKeyChainStore存放用户账号密码组件Reachability监测网络状态DateTools友好化时间MBProgressHUD一款提示框第三方库MWPhotoBr...
一早起来满世界都是巧克力跟花,除了合照,美食,小礼物,朋友圈里全是腻歪的你爱他,他爱她,她爱他,他爱他,知道你们浓情蜜意,要不今晚轰趴大醉,放过朋友圈,放过单身狗?情人间的节日每年都有,而且还特别多,白色情人节,4.19,5.20,6.9,七夕,9.6,再加上邂逅日,表白日...
有些时候我们不希望把一些编译的东西提交到Git中,.gitignore可以方便管理我们不需要提交的文件,自动过滤设置的文件。 Git提供了一种可配性很强的机制来允许用户将指定的文件或目录排除在版本控制之外,它会检查代码仓库的根目录下是否存在一个名为.gitignore的文件...
我不是一个狂热的乒乓球球迷,可能我只能算是纯路人粉吧。但身为中国人,乒乓球是我们国家的“国球”! 但凡有一点点了解奥运会的,都知道乒乓球是我们国家绝杀其他国家的一项运动! 一项令国人骄傲的运动!毕竟像马龙他们很多人都已经包揽过很多大满贯了! 而今晚微博上所暴露出的政治...
吃1、日本料理大连的日料整体水平不错,但价位不低,推荐的有红叶日本料理和鱼旨寿司红叶一定要去二七广场那家总店,比较远,打车去吧,就说去“二七广场,红叶总店”, 打车35左右自助的话大概每人200~300,要是人多,还喝酒比较合适,自助的酒免费;也可以单点,人均100~200...iOS 异步请求完成状态判断,Afnetworking 多个请求完成判断 - 简书
iOS 异步请求完成状态判断,Afnetworking 多个请求完成判断
在实际开发中我们通常会遇到这样一种需求:某个页面加载时通过网络请求获得相应的数据,再做某些操作。有时候加载的内容需要通过好几个请求的数据组合而成,比如有两个请求A和B,我们通常为了省事,会将B请求放在A请求成功的回调中发起,在B的成功回调中将数据组合起来,这样做有明显的问题:1.请求如果多了,需要写许多嵌套的请求2.如果在除了最后一个请求前的某个请求失败了,就不会执行后面的请求,数据无法加载3.请求变成同步的,这是最大的问题,在网络差的情况下,如果有n个请求,意味着用户要等待n倍于并发请求的时间才能看到内容同步请求这么low的方式当然是不可接受的,所以我们要并发这些请求,在所有请求都执行完成功回调后,再做加载内容或其他操作,考虑再三,选择用GCD的dispatch_group。dispatch_group通常有两种用法,一种是dispatch_group_async(&#dispatch_group_t group#&, &#dispatch_queue_t queue#&, &#^(void)block#&)创建一个dispatch_group_t, 将并发的操作放在block中,在dispatch_group_notify(&#dispatch_group_t group#&, &#dispatch_queue_t queue#&, &#^(void)block#&)的block中执行多组block执行完毕后的操作,对于网络请求来说,在请求发出时他就算执行完毕了,并不会等待回调,所以不满足我们的需求。所以采用另一种用法:使A.使用dispatch_group_enter和dispatch_group_leave
用dispatch_group_enter和dispatch_group_leave,这种方式使用更为灵活,enter和leave必须配合使用,有几次enter就要有几次leave,否则group会一直存在。当所有enter的block都leave后,会执行dispatch_group_notify的blockB.捷径:增进一个记数位 loadingcout 判断请求次数
//判断数据是不是加载完全计数位@property (nonatomic, assign) NSInteger loadC{if ([@"success" isEqualToString:[responseObject objectForKey:@"message"]]) {weakSelf.loadCount++;[weakSelf judgeIsAreadyLoaded];}执行判断计数位是否符合,符合的话我们把当前加载占位图给消失,loading的动画也消失- (void)judgeIsAreadyLoaded{if (_loadCount &= 7) {_loadingView.hidden = YES;[SVProgressHUD dismiss];}}c.高级方法 转摘 /moona/p/5462463.html使用dispatch_group_enter和dispatch_group_leave,这种方式使用更为灵活,enter和leave必须配合使用,有几次enter就要有几次leave,否则group会一直存在。当所有enter的block都leave后,会执行dispatch_group_notify的block。我们当然可以在网络请求前enter,在执行完每个请求的成功回调后leave,再在notify中执行内容加载,这样看来问题就解决了,但还是有点小小不爽,每次发起组请求我都得创建group,写一堆的enter和leave,既麻烦也不利于复用,很自然我们想到把他封装一下,最好能做到将一个网络请求加到组里,而不用修改原先的网络请求代码,就像这样:按 Ctrl+C 复制代码按 Ctrl+C 复制代码如果我想做到这种效果,肯定要到网络单例层去做些修改,但我又不想改变现有的底层请求方法,所以我采用了method_exchangeImplementations(&#Method m1#&, &#Methodm2#&) 这个函数,基于现有的底层请求方法,实现一套组的请求方法,替换掉原先的方法,在组请求都发送完毕后,再换回原先的方法。但这里有一些可怕的坑要处理,因为使用方法替换是很危险的。1.我做了替换后,正常的非组网络请求也会走替换后的方法,但我不需要他走替换后的方法。2.假如我同时发起了多个组请求,组和组之间要如何区分,不同的组是不应该相互影响的。一开始我考虑给请求一个mark,标记他是属于哪个group的,但这需要你已经把请求封装成了一个对象,如果你的项目和我的一样,只是执行一个方法,是不好给他加标记的。在一阵头脑风暴后,我决定用队列来区分每个gorup。具体做法就是创建每个group时,开启一个队列,给队列动态添加group属性,一个队列对应一个group。在队列中替换方法,发起组里的请求,再替换回原先的方法,这样在replacedmethod里只需要拿到当前的队列,就可以拿到group,如果group是nil,说明是正常的非组请求,执行originalmethod;如果group不是nil,根据group来enter和leave,每个group也能区分开。创建group时,给group添加了一个errorArray,用来记录组里请求的error,只要errorArray不为空,就会走组失败的block。下面上代码:typedefvoid(^BlockAction)();typedefvoid(^GroupResponseFailure)(NSArray *errorArray);staticchargroupErrorKstaticcharqueueGroupK
- (void)sendPOSTRequestInGroup:(NSString *)strURL withData:(NSDictionary *)data paramForm:(ParamForm)paramForm withTimeout:(NSTimeInterval)timeout showAlert:(BOOL)show
success:(BlockResponse)success failure:(BlockResponseFailure)failure {dispatch_group_t group= objc_getAssociatedObject([NSOperationQueue currentQueue], &queueGroupKey);//如果是非组请求if(group ==nil) {//执行original method[self sendPOSTRequestInGroup:strURL withData:data paramForm:paramForm withTimeout:timeout showAlert:show success:success failure:failure];}dispatch_group_enter(group);//执行original method[self sendPOSTRequestInGroup:strURL withData:data paramForm:paramForm withTimeout:timeout showAlert:show success:^(idresponseObject) {success(responseObject);dispatch_group_leave(group);} failure:^(NSError *error) {NSMutableArray*arrayM = objc_getAssociatedObject(group, &groupErrorKey);[arrayM addObject:error];failure(error);dispatch_group_leave(group);}];}- (void)sendGroupPostRequest:(BlockAction)requests success:(BlockAction)success failure:(GroupResponseFailure)failure {if(requests ==nil) {}dispatch_group_t group=dispatch_group_create();objc_setAssociatedObject(group,&groupErrorKey, [NSMutableArray array], OBJC_ASSOCIATION_RETAIN_NONATOMIC);Method originalPost= class_getInstanceMethod(self.class, @selector(sendPOSTRequest:withData:paramForm:withTimeout:showAlert:success:failure:));Method groupPost= class_getInstanceMethod(self.class, @selector(sendPOSTRequestInGroup:withData:paramForm:withTimeout:showAlert:success:failure:));NSOperationQueue*queue =[[NSOperationQueue alloc] init];objc_setAssociatedObject(queue,&queueGroupKey, group, OBJC_ASSOCIATION_RETAIN_NONATOMIC);queue.qualityOfService=NSQualityOfServiceUserIqueue.maxConcurrentOperationCount=3;[queue addOperationWithBlock:^{method_exchangeImplementations(originalPost, groupPost);requests();//发出请求后就可以替换回original method,不必等待回调,尽量减小替换的时间窗口method_exchangeImplementations(originalPost, groupPost);dispatch_group_notify(group, dispatch_get_main_queue(),^{NSMutableArray*arrayM = objc_getAssociatedObject(group, &groupErrorKey);if(arrayM.count &0) {if(failure) {failure(arrayM.copy);}}elseif(success) {success();}});}];}
- (void)sendPOSTRequestInGroup:(NSString *)strURL withData:(NSDictionary *)dataparamForm:(ParamForm)paramForm withTimeout:(NSTimeInterval)timeoutshowAlert:(BOOL)show success:(BlockResponse)successfailure:(BlockResponseFailure)failure替换网络工具层的底层post请求sendPOSTRequest:withData:paramForm:withTimeout:showAlert:success:failure:这样在- (void)sendGroupPostRequest:(BlockAction)requests success:(BlockAction)success failure:(GroupResponseFailure)failurerequests block中,把网络请求扔进去,单个请求本身的success和failure都能执行,success执行组成功的代码,failure中可以拿到每个请求的error,作相应处理。
一. 重点: 1.dispatch_queue_create(生成Dispatch Queue) 2.Main Dispatch Queue/Global Dispatch Queue 3.dispatch_set_target_queue 4.dispatch_after...
近一年内陆续面试了不少人了,从面试者到面试官的转变让我对 iOS 招聘有了更多的感受。经过了前段时间的一大波面试,我们终于找到了志同道合的小伙伴,面试也暂时告一段落了。总结下面试人过程中的感受,你也可以读到我们对简历、算法、性格、iOS 基础、底层知识的看法和一些常问的面试...
1、主线程队列 VS 分线程队列 dispatch_sync 和 dispatch_async 区别: dispatch_async(queue,block) async 异步队列,dispatch_async 函数会立即返回, block会在后台异步执行。 dispatc...
为什么使用并发组请求? 在实际开发中我们通常会遇到这样一种需求:某个页面加载时通过网络请求获得相应的数据,再做某些操作,有时候加载的内容需要通过好几个请求的数据组合而成,比如有两个请求A和B,我们通常为了省事,会将B请求放在A请求成功的回调中发起,在B的成功回调中将数据组合...
NSThread和NSOperation就不多说,NSOperation就是将GCD封装成对象来便于开发者调用。苹果官方对GCD是这样说明的:开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。Dispatch Queue是执行处理的等待队列,我们...
看简书里有人写的挺有意思,也来凑凑热闹。 1 你穿一袭紫罗兰打我身边掠过 周边的灯红酒绿 都变成了沙漠 2 我本是个不修边幅的粗人 遇见你之后 也知道了花的芳香 3 世界好纷扰啊 跟我去无人的山上 我愿为你修一生的阶梯
諸位同學,大家好!感應的道理很深,感應的事蹟很廣,古人對我們的勉勵很多,愛護備至。古書裡面教導我們,世出世間法,尤其是善法,「信心」是成就第一個因素。無論是希求在一生當中,得到幸福美滿的果報,或者是學佛,希望這一生當中能夠往生淨土,親近阿彌陀佛,也都在「信心」。尤其應當警覺...
1、 何夕刚来公司,就吸引了大部分男生的注意,其中就包括林旭。 这天何夕第一天来到公司,胸前挂着实习生的牌子,同期还有几个应届生,他们一个个在做着自我介绍。 刚大学毕业的何夕,留着干净整齐的刘海,散着乌黑的长发。没有职场老手的凌厉强势,她穿衣也还没褪去大学生的青春靓丽,眼神...
原标题:女子130万拆迁补偿款险遭骗,真警察面前仍相信“假警察” 利用公检法机关名义实施电信诈骗已是老套路,但在骗子的层层设计下依然有人会掉入陷阱。 澎湃新闻()25日从杭州萧山区公安分局获悉,当地警方日前处置了1起正在发生的电信诈骗案,当警员...}

我要回帖

更多关于 ios dispatch async 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信