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

在项目中往往会遇到这种需求: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);
}

打印出的结果





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值