美文网首页基础部分
iOS 多个网络请求并发执行的解决方案

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

作者: VincentHK | 来源:发表于2017-07-13 14:42 被阅读741次

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

    20161229132112431.png

    二.通过 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

    20161229143724794.png

    另外,通过下面的方法也可以实现
    <span style="font-size:18px;">/// Like -rac_liftSelector:withSignals:, but accepts an array instead of
    /// a variadic list of arguments.

    • (RACSignal *)rac_liftSelector:(SEL)selector withSignalsFromArray:(NSArray *)signals;</span>

    具体实现代码
    [self rac_liftSelector:@selector(responseA:B:) withSignalsFromArray:@[[TestViewModel fetchList1], [TestViewModel fetchList2]]];

    • (void)responseA:(id)a B:(id)b {
      NSLog(@"%@, %@", a, b);
      }
      打印出的结果
    20161229144215293.png

    相关文章

      网友评论

      • 35eb825ad7f4://1.三个请求对应三次信号等待
        这里执行等待
        //2.在这里 进行请求后的方法
        NSLog(@"string1:___%@", _string1);
        NSLog(@"string2:___%@", _string2);
        NSLog(@"string3:___%@", _string3);
        老哥从哪拷过来并没有经过深思熟虑吧! 执行的位置放错了不知道吗
      • 鬼丶白:在不

      本文标题:iOS 多个网络请求并发执行的解决方案

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