iOS 等待块直到完成

问题描述 投票:0回答:2

我创建了一个使用 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 和 Google 中搜索各种主题,但找不到任何解决方案。

请帮忙。

ios objective-c
2个回答
3
投票

有几种方法可以解决您的问题。您可以使用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);
        }
    }];

}

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];
}
© www.soinside.com 2019 - 2024. All rights reserved.