美文网首页
iOS 异步请求等待传值方法小结

iOS 异步请求等待传值方法小结

作者: 90后的思维 | 来源:发表于2016-12-13 13:56 被阅读35次

    总感觉这个标题怪怪的,但是我自身词汇有限,也不知道怎么描述好了.用一个简单的需求来解释一下吧.我之前开发的一个项目,需要向服务器上传图片,多图片上传,然后每次上传之后会返回一个图片的AID, 然后需要所有图片上传完成之后, 拿着一个全是AID的数组作为参数进行另一个异步请求...好吧,我感觉又绕了...

    前几天,我在一个技术交流圈,看到一个朋友去JINGDONG的面试题, 其中一个题目的描述是:有a、b、c、d 4个异步请求,如何判断a、b、c、d都完成执行?, 跟我上面的需求大同小异.

    所以在这儿,我把我工作中曾经用到过的一些方法做一个小的总结,有遗漏的或者错误的地方,请大家留意指正,非常感谢哈!!!

    特别注意:所有的代码都基于JINGDONG这道面试题, 不过我只打印了A和B而已..

    小结

    1. RunLoop

    需要注意一点: 这儿用的是NSURLSession, 不是AFN, 所以block里面的线程是子线程,不是主线程, 不能直接使用CFRunLoopGetCurrent

    CFRunLoopGetCurrent : Returns the CFRunLoop object for the current thread.

    CFRunLoopGetMain: Returns the main CFRunLoop object.

    NSURLSessionDataTask*task = [[NSURLSessionsharedSession] dataTaskWithRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.baidu.com"]] completionHandler:^(NSData* _Nullable data,NSURLResponse* _Nullable response,NSError* _Nullable error) {NSLog(@"A");CFRunLoopStop(CFRunLoopGetMain());    }] ;    [task resume];CFRunLoopRun();NSLog(@"B");

    2. GCD的group

    dispatch_group_notify就是需要等queue里面的子线程都执行完毕之后才会执行

    这种方法比较常见, 不多说

    dispatch_group_t group = dispatch_group_create();dispatch_queue_t queue = dispatch_get_global_queue(0,0);dispatch_group_async(group, queue, ^{        NSLog(@"A");});dispatch_group_notify(group, dispatch_get_main_queue(), ^{        NSLog(@"B");});

    3. dispatch_barrier_async

    barrier的中文意思就是障碍, 屏障

    一般使用dispatch_barrier_async, 会让barrier之前的线程执行完成之后才会执行barrier后面的操作

    dispatch_queue_tqueue =  dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue, ^{NSLog(@"A");    });dispatch_async(queue, ^{NSLog(@"C");    });    dispatch_barrier_async(queue, ^{NSLog(@"拿到了A的值");    });dispatch_async(queue, ^{NSLog(@"D");    });dispatch_async(queue, ^{NSLog(@"E");    });dispatch_async(queue, ^{NSLog(@"F");    });

    4.NSOperationQueue

    主要就是用到NSOperationQueue的一个对象方法-addDependency

    需要注意一点:waitUntilFinished如果是YES,必须等到queue中所有Operation执行完毕之后, 才会打印HAHA, 反之的话,HAHA的打印顺序是随机的了,就看哪个线程跑得快了...

    NSOperationQueue*queue = [[NSOperationQueuealloc] init];NSBlockOperation*p1 = [NSBlockOperationblockOperationWithBlock:^{NSLog(@"A");    }];NSBlockOperation*p2 = [NSBlockOperationblockOperationWithBlock:^{NSLog(@"B");    }];NSBlockOperation*p3 = [NSBlockOperationblockOperationWithBlock:^{NSLog(@"C");    }];    [p3 addDependency:p1];    [p3 addDependency:p2];// waitUntilFinished是否阻塞当前线程[queue addOperations:@[p1,p2,p3] waitUntilFinished:NO];// 如果是NO,那么这行打印就是随机的, 反之就是等A,B,C都打印完之后才执行NSLog(@"HAHA");

    5. 使用AFN中的batchOfRequestOperations

    这个和GCD一样, 我工作中比较常用的一种方法

    batchOfRequestOperations方法其实是AFHTTPRequestOperation的父类AFURLConnectionOperation的一个方法.

    这儿的waitUntilFinished同4. NSOperationQueue

    progressBlock一般用在进度计算中, 比如执行了多少百分比, 可以自定义一些炫酷动画

    AFHTTPRequestOperation *queue = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.baidu.com"]]];    [queue setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation,idresponseObject) {NSLog(@"A");    } failure:^(AFHTTPRequestOperation *operation,NSError*error) {NSLog(@"A");    }];    [queue resume];    AFHTTPRequestOperation *queue2 = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.baidu.com"]]];    [queue2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation,idresponseObject) {NSLog(@"B");    } failure:^(AFHTTPRequestOperation *operation,NSError*error) {NSLog(@"B");    }];    [queue2 resume];NSArray*operations = [AFHTTPRequestOperation batchOfRequestOperations:@[queue, queue2] progressBlock:^(NSUIntegernumberOfFinishedOperations,NSUIntegertotalNumberOfOperations) {NSLog(@"%ld/%ld", numberOfFinishedOperations, totalNumberOfOperations);    } completionBlock:^(NSArray*operations) {NSLog(@"C");    }];    [[NSOperationQueuemainQueue] addOperations:operations waitUntilFinished:NO];

    6.其他

    老早以前, 我一般是在一个异步请求中的completionBlock或者successBlock中拿到需要的值, 为空判断后,直接在block里面再写一个异步线程...其实这样的写法可能很多人都用过,但是代码的阅读性太弱了,花括号太多,看的眼花缭乱的...

    其实还可以设置flag进行判断等等方法...

    暂时就想到这么多, 还有别的方案的话, 欢迎留言哈,大家共同学习!!!

    相关文章

      网友评论

          本文标题:iOS 异步请求等待传值方法小结

          本文链接:https://www.haomeiwen.com/subject/blxbmttx.html