我创建了一个使用 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 中搜索各种主题,但找不到任何解决方案。
请帮忙。
有几种方法可以解决您的问题。您可以使用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);
}
}];
}
一个丑陋的解决方案,但它有效!
__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];
}