ios 当两个API调用都已完成时,调用完成?

sirbozc5  于 11个月前  发布在  iOS
关注(0)|答案(4)|浏览(85)

在一个类的init方法中,我触发了两个API调用,它们通过委托进行响应。当这两个调用都返回了它们的数据时,类本身需要发送一个完成处理程序。我尝试过使用GCD和一个调度组来完成这一点,但我不完全确定我需要把notify部分放在代码的什么地方。委托方法(didReceiveData被调用两次,每次调用一次),可以是任何顺序,等等,基本上我需要一种方法来知道它们何时完成,并在一个completion中返回它们的两组数据。
对于从哪里开始开始,我有点困惑,我已经做了一些调查,我不能让GCD或NSOperation方法工作。示例停留足够长的时间,以便两个调用返回,但是因为它们几乎同时返回,所以它们不能检查另一个是否已经完成。我不知道如何检查,也不知道在哪里检查。

vatpfxk5

vatpfxk51#

我已经使用NSNotification完成了这一点。基本上,当每个API请求完成时,发布一个NSNotification。添加一个NSNotification侦听器以管理每个通知被触发时的跟踪状态。一旦侦听器接收到两个通知,则可以调用completionnotification。

i34xakig

i34xakig2#

你总是可以给调用这两个API请求的类设置一个计数器(整数属性或调用方法中的静态整数值),然后只在计数器具有特定值时才执行返回块应该执行的任何操作,否则增加/减少计数器并等待另一个响应。这是一个糟糕的过程,但它的工作量最小。
如果你想以正确的方式做到这一点,有很多方法:

  • 你可以创建一个专门处理这两个请求的类,并将这两个响应都作为一个属性。然后在响应块中设置目标响应属性,并检查是否已经设置了另一个响应,如果是,则调用输入块。
  • 你可以创建一个类,它接收一个请求数组和一个回调块,然后你可以使用一个内部计数器或者简单地保存响应。然后你对每个接收到的响应计数,看看你是否有足够的数量来调用一个输入回调块。
  • 你可以通过块来创建一个系统,你传入一个可变字典,每个块都应该设置一个特定的键(带有响应对象或状态码或其他东西),然后在每个回调中检查字典中是否有足够的对象来继续这个过程。

有太多的可能性了.

v2g6jxz6

v2g6jxz63#

如果你使用的是一个调度组,每个调用只需要关心它自己的完成。一般的想法如下:

初始化方法:从一个空的调度组开始(新创建的,或者已经平衡了对dispatch_group_enterdispatch_group_leave的调用)。在进行每个API调用之前,调用dispatch_group_enter。一旦完成了所有API调用,就用完成处理程序调用dispatch_group_notify
Delegate方法:调用调度组上的dispatch_group_leave。如何将调度组提供给您的delegate,很大程度上取决于您的代码如何工作。

只有当对dispatch_group_enter的调用次数等于对dispatch_group_leave的调用次数时,您传递给dispatch_group_notify的块才会排队到目标队列。在调用dispatch_group_notify时,您已经为每个请求调用了一次dispatch_group_enter,因此每个请求都需要一个dispatch_group_leave,当请求返回它们的数据时会被触发。注意,调度组并不关心请求返回的顺序,因为它看到的都是对dispatch_group_leave的调用,没有额外的参数。

von4xj4u

von4xj4u4#

我可以在没有delegates的情况下完成这个,所以我不知道你对此有什么感觉,但这确实有效。我确实需要调整一下代码,所以可能会有一两个错误,因为可能有些变量不存在,因为我删除了它们。

类API

API.h
-(void)getMyDataWithCompletionHandler:(void (^)(NSMutableArray *firstData, NSMutableArray *secondData))Final_callBack;
API.m

-(void)getMyDataWithCompletionHandler:(void (^)(NSMutableArray *firstData, NSMutableArray *secondData))Final_callBack {

    NSString *firstURL = @"www.firstURL.com";
    NSString *secondURL = @"www.secondURL.com";

    __block bool firstIsBack = false;
    __block bool secondIsBack = false;

    __block NSMutableArray *firstArray = [NSMutableArray new];
    __block NSMutableArray *secondArray = [NSMutableArray new];

    [self getFirstData:firstURL
             withCallBack:^(NSMutableArray *firstData) {
              firstIsBack = true;
              firstArray = firstData;
                if (firstIsBack && secondIsBack){
                        Final_callBack(firstArray,secondArray);
                }      
                    
              }
    }];

    [self getSecondData:secondURL
             withCallBack:^(NSMutableArray *secondData) {
              secondIsBack = true;
              secondArray = secondData;
                if (firstIsBack && secondIsBack){
                  Final_callBack(firstArray,secondArray);
                }      
                    
              }
    }];    
}

字符串

视图控制器

@property (strong, nonatomic) NSMutableArray *finalFirstArray; @property (strong, nonatomic) NSMutableArray *finalSecondArray;

- (void)viewDidLoad{
    [super viewDidLoad];
    API *myApi = [API new];
    //make first call to 
    [myApi getMyDataWithCompletionHandler:^(NSMutableArray *firstData, NSMutableArray *secondData) {
         _finalFirstArray = firstData;
         _finalSecondArray = secondData;
    }];
}

相关问题