iOS等待块直到完成

时间:2016-09-08 01:50:01

标签: ios objective-c

我创建了一个使用AFNetworking库的块void函数。此函数用于GET请求,并使用如此。

[Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) {
    //use response here
}];

一切正常,但是当我在需要返回值的函数中使用此块时,我真的很头疼。例如。

+ (NSArray*)OnlineClients
{
    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL];
    __block NSArray *clients = [[NSArray alloc] init];
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) {
        clients = [response componentsSeparatedByString: @","];
    }];

    return clients;
}

OnlineClients数组函数始终返回0项,因为请求块未完成完成。

那么,我如何等待块完成以获取函数返回的响应请求?

我一直在StackOverflow和谷歌搜索各种主题,但找不到任何解决方案。

请帮忙。

2 个答案:

答案 0 :(得分:1)

有几种方法可以解决您的问题。您可以使用dispatch_group或dispatch_semaphore在返回值之前等待来自异步调用的响应,或者修改您的方法以使用块来回调响应。请看下面的代码。要注意dispatch_group和dispatch_semaphore将阻止当前线程等到另一个触发信号,因此,不应在主线程上使用它。在我看来,我会建议第三种解决方案。 我希望它会对你有所帮助。

//1
+ (NSArray*)OnlineClients
{
    dispatch_group_t serviceGroup = dispatch_group_create();

    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL];
    __block NSArray *clients = [[NSArray alloc] init];
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) {
        clients = [response componentsSeparatedByString: @","];
        dispatch_group_leave(serviceGroup);
    }];

    dispatch_group_enter(serviceGroup);

    return clients;
}

//2
+ (NSArray*)OnlineClients
{
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);

    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL];
    __block NSArray *clients = [[NSArray alloc] init];
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) {
        clients = [response componentsSeparatedByString: @","];
        dispatch_semaphore_signal(sema);
    }];

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    return clients;
}

//3
+ (void)getOnlineClientsWithCompletionBlock:(void (^) (NSArray *clients))completionBlock
{   
    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL];
    __block NSArray *clients = [[NSArray alloc] init];
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) {
        clients = [response componentsSeparatedByString: @","];
        if (completionBlock) {
            completionBlock(clients);
        }
    }];

}

答案 1 :(得分:0)

一个丑陋的解决方案,但是可行!

__block BOOL isChecked = NO;
YourService *yourService = [[YourService alloc] init];
[yourService checkStatus:string completionHandler:^(BOOL isSuccessful, Error *err) {
    isValid = err ? NO : isSuccessful;
    isChecked = YES;
}];
while (!isChecked) {
    [NSThread 0.6];
}