iOS 多个网络请求并发执行的解决方案

来源:互联网 发布:java开发合同管理系统 编辑:程序博客网 时间:2024/05/16 01:43

在项目中往往会遇到这种需求:UI 的更新要在2~3个网络请求后才执行.这里提供两种执行方案.

一.利用 GCD

通过 gcd_group可以解决这个问题.具体做法如下

////  ViewController.m//  tableview////  Created by myMac on 16/12/26.//  Copyright © 2016年 myMac. All rights reserved.//#import "ViewController.h"typedef void(^FinishNetwork)();@interface ViewController ()@property (nonatomic, copy  ) FinishNetwork block;@property (nonatomic, copy  ) NSString      *string1;@property (nonatomic, copy  ) NSString      *string2;@property (nonatomic, copy  ) NSString      *string3;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    [self initData];}- (void)initData {        // 创建信号量    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, ^{                // 请求一        //这里通过 block 表示请求结束,并标记一个信号量        [self getList1:^{                        dispatch_semaphore_signal(semaphore);        }];            });    dispatch_group_async(group, queue, ^{                // 请求二        [self getList2:^{                        dispatch_semaphore_signal(semaphore);        }];    });    dispatch_group_async(group, queue, ^{                // 请求三        [self getList3:^{                        dispatch_semaphore_signal(semaphore);        }];    });        dispatch_group_notify(group, queue, ^{                //在这里 进行请求后的方法        NSLog(@"string1:___%@", _string1);        NSLog(@"string2:___%@", _string2);        NSLog(@"string3:___%@", _string3);                // 三个请求对应三次信号等待        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);            });    }- (void)getList1:(FinishNetwork)block {        NSLog(@"加载列表1");    self.string1 = @"加载列表1";    }- (void)getList2:(FinishNetwork)block {        NSLog(@"加载列表2");    self.string2 = @"加载列表2";    }- (void)getList3:(FinishNetwork)block {        NSLog(@"加载列表3");    self.string3 = @"加载列表3";    }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end

打印结果如下




二.通过 RAC

利用 RAC 的 merge 也可以解决这个问题,具体做法如下

ViewController

[[RACSignal merge:@[[TestViewModel fetchList1], [TestViewModel fetchList2]]] subscribeNext:^(id x) {                NSLog(@"%@", x);        if (!_string1.length) {            self.string1 = x;        } else {            self.string2 = x;        }            } completed:^{        NSLog(@"string1: %@\nstring2: %@ \n", _string1, _string2);    }];


ViewModel

#import "TestViewModel.h"@implementation TestViewModel+ (RACSignal *)fetchList1 {        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {                [subscriber sendNext:@"请求1"];        [subscriber sendCompleted];        return nil;    }];    }+ (RACSignal *)fetchList2 {        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {                [subscriber sendNext:@"请求2"];        [subscriber sendCompleted];        return nil;    }];    }@end

   打印出的结果



       另外,通过下面的方法也可以实现

/// Like -rac_liftSelector:withSignals:, but accepts an array instead of/// a variadic list of arguments.- (RACSignal *)rac_liftSelector:(SEL)selector withSignalsFromArray:(NSArray *)signals;

         具体实现代码

[self rac_liftSelector:@selector(responseA:B:) withSignalsFromArray:@[[TestViewModel fetchList1], [TestViewModel fetchList2]]];

- (void)responseA:(id)a B:(id)b {    NSLog(@"%@, %@", a, b);}

打印出的结果





0 0
原创粉丝点击