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

sirbozc5  于 2023-11-19  发布在  iOS
关注(0)|答案(4)|浏览(129)

在一个类的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

  1. -(void)getMyDataWithCompletionHandler:(void (^)(NSMutableArray *firstData, NSMutableArray *secondData))Final_callBack {
  2. NSString *firstURL = @"www.firstURL.com";
  3. NSString *secondURL = @"www.secondURL.com";
  4. __block bool firstIsBack = false;
  5. __block bool secondIsBack = false;
  6. __block NSMutableArray *firstArray = [NSMutableArray new];
  7. __block NSMutableArray *secondArray = [NSMutableArray new];
  8. [self getFirstData:firstURL
  9. withCallBack:^(NSMutableArray *firstData) {
  10. firstIsBack = true;
  11. firstArray = firstData;
  12. if (firstIsBack && secondIsBack){
  13. Final_callBack(firstArray,secondArray);
  14. }
  15. }
  16. }];
  17. [self getSecondData:secondURL
  18. withCallBack:^(NSMutableArray *secondData) {
  19. secondIsBack = true;
  20. secondArray = secondData;
  21. if (firstIsBack && secondIsBack){
  22. Final_callBack(firstArray,secondArray);
  23. }
  24. }
  25. }];
  26. }

字符串

视图控制器

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

  1. - (void)viewDidLoad{
  2. [super viewDidLoad];
  3. API *myApi = [API new];
  4. //make first call to
  5. [myApi getMyDataWithCompletionHandler:^(NSMutableArray *firstData, NSMutableArray *secondData) {
  6. _finalFirstArray = firstData;
  7. _finalSecondArray = secondData;
  8. }];
  9. }

展开查看全部

相关问题