Objective c 目标-C–;正在等待两个异步方法完成

Objective c 目标-C–;正在等待两个异步方法完成,objective-c,ios,cocoa,asynchronous,wait,Objective C,Ios,Cocoa,Asynchronous,Wait,我调用了四个方法,我想按同步顺序执行,前两个是同步的,后两个是异步的(从URL获取数据) 伪代码: - (void)syncData { // Show activity indicator [object sync]; // Synchronous method [object2 sync]; // Synchronous method BOOL object3Synced = [object3 sync]; // Async method BOOL

我调用了四个方法,我想按同步顺序执行,前两个是同步的,后两个是异步的(从URL获取数据)

伪代码:

- (void)syncData {

    // Show activity indicator
    [object sync]; // Synchronous method
    [object2 sync]; // Synchronous method
    BOOL object3Synced = [object3 sync]; // Async method
    BOOL object4Synced = [object4 sync]; // Async method
    // Wait for object3 and object4 has finished and then hide activity indicator
}

如何实现这一点?

您需要启动第一个异步方法并使用完成块。在第一个异步方法的完成块中,您将启动第二个异步方法。尽管这使得使用异步方法变得无关紧要。

假设您确实有某种方式知道异步方法何时完成,您可能想要的是:

- (void)syncData {

    // Show activity indicator
    [object sync]; // Synchronous method
    [object2 sync]; // Synchronous method

    _object3Synced = _object4Synced = NO;
    [object3 syncWithCompletionHandler:
          ^{
               _object3Synced = YES;
               [self considerHidingActivityIndicator];
          }]; // Async method
    [object4 syncWithCompletionHandler:
          ^{
               _object4Synced = YES;
               [self considerHidingActivityIndicator];
          }]; // Async method
}

- (void)considerHidingActivityIndicator
{
     if(_object3Synced && _object4Synced)
     {
         // hide activity indicator, etc
     }
}

您可以创建
UIActivityInIndicator
的子类,添加
activityCount
属性并实现这两个附加方法:

- (void)incrementActivityCount
{
    if(_activityCount == 0)
    {
        [self startAnimating];
    }
    _activityCount++;
}

- (void)decrementActivityCount
{
    _activityCount--;
    if(_activityCount <= 0)
    {
        _activityCount = 0;
        [self stopAnimating];
    }
}
-(void)递增活动计数
{
如果(_activityCount==0)
{
[自启动];
}
_activityCount++;
}
-(无效)递减计数
{
_活动计数--;
如果(_activityCount使用屏障:

void dispatch\u barrier\u async(dispatch\u queue\u t queue,dispatch\u block\u t block);

提交用于异步执行的屏障块并立即返回

当屏障块到达专用并发服务器的前端时 队列,它不会立即执行。 相反,队列等待当前执行的块完成执行。 在这一点上 队列自行执行屏障块。之后提交的任何块 在屏障块完成之前,不会执行屏障块

此示例输出
1 2 3 4 done
虽然是异步的,但它可以
1 2 4 3 done
。因为我知道您希望处理活动指示器,所以这不重要

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    @autoreleasepool {
        dispatch_queue_t queue = dispatch_queue_create("com.myqueue", 0);
        dispatch_sync(queue,  ^(){NSLog(@"1");} );
        dispatch_sync(queue,  ^(){NSLog(@"2");});
        dispatch_async(queue, ^(){NSLog(@"3");});
        dispatch_async(queue, ^(){NSLog(@"4");});
        dispatch_barrier_sync(queue, ^(){NSLog(@"done");});
    }
}
#导入
int main(int argc,char*argv[]){
@自动释放池{
dispatch\u queue\u t queue=dispatch\u queue\u create(“com.myqueue”,0);
调度同步(队列,^(){NSLog(@“1”);});
调度同步(队列,^(){NSLog(@“2”);});
调度异步(队列,^(){NSLog(@“3”);});
调度异步(队列,^(){NSLog(@“4”);});
调度(队列,^(){NSLog(@“done”);});
}
}

有关测试异步代码的其他方法,请参阅:

此处的伪代码不太好。为了帮助我们了解您使用的异步机制。@PeterWarbo如果
object3
object4
有一些界面在其操作完成时通知您,您需要编辑帖子并向我们显示该界面。
object3
正在通过
NSURLRequest
下载文件,
object4
正在使用Facebook SDK下载数据(我相信幕后也在使用
NSURLRequest
是的,你失去了使两个异步调用并行的好处,但你并没有失去所有的好处——至少它脱离了UI线程并且没有挂起。如果第二个异步方法依赖于第一个异步方法的处理,那么这就是方法。否则,另一个异步方法会回答一个问题。)你更好。是的,顺便说一句,我没有否决投票-OPs的问题是模糊的伪代码。而且,如果它们相互依赖,你的答案会更好。这与我想象的,我也会用块完成处理程序实现它的方式差不多…感谢你的输入+1-当然object4方法不能依赖于对e object3方法调用…如果您不介意异步方法的并发执行,请使用
DISPATCH\u QUEUE\u concurrent
(在iOS 5中提供)创建队列时使用0。这假设两个异步操作都在同一队列上,并且该队列可以从计划屏障的代码访问。@Daij Djan这些当然应该在主线程上调用,任何与UI有关的操作都应该调用。无论何时处理upda的完成块在UI中,您应该确保它们被调度到主队列。