我创建了一个使用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和谷歌搜索各种主题,但找不到任何解决方案。
请帮忙。
答案 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];
}