我正在使用AFN处理我的API调用的应用程序。我尝试使用prepare for segue方法初始化目标视图控制器中的某些数据。问题是,因为AFNetworking在后台线程中完成它的工作然后运行成功:/ failure:在主线程上,我的segue发生在我的成功块之前,并且我需要传递给目标VC的数据都不是到达那里。
我的问题是双重的:
1)有没有办法阻止prepareForSegue
中的主线程,直到AFNetworking在后台线程上运行完毕,所以我可以在segue发生之前利用响应对象?
2)这似乎是一个非常常见的设计问题。我会以错误的方式做这件事吗?我应该在prepareForSegue
进行网络通话吗?
以下是我在代码中尝试做的事情:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"mySegue"])
{
// Get reference to the destination view controller
DestinationViewController *vc = [segue destinationViewController];
NSMutableArray* responseArray = [[AFNClient sharedClient] getDataWithParameters:@{@"param":@"param"}
CompletionBlock:^(NSError *error) {}]];
//I want to block here
NSLog(@"%@", [vc responseArray]); // <-This logs as an empty array because it's running parallel to to AFN
[vc setArray:responseArray]
}
}
并且是AFNClient
getDataWithParameters:CompletionBlock
方法定义
- (NSMutableArray*) getDataWithParameters:(NSDictionary*)parameters
CompletionBlock:^(NSError *error)block
{
NSMutableArray *returnArray = [[NSMutableArray alloc] initWithArray:@[]];
//build path string
NSString *pathString = @"apiPath"
[self GET:pathString parameters:parameters
success:^(NSURLSessionDataTask *task, id responseObject) {
[returnArray setArray:responseObject];
block(nil);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
block(error);
}];
return returnArray;
}
提前感谢您的帮助! -ja
答案 0 :(得分:3)
你真的不想阻止线程。使用顶部视图打开新的视图控制器,该视图只有一个标记为“正在下载...”(或运行微调器)。在下载的完成块中,调用主线程[self performSelectorOnMainThread ...]上的例程,该例程更新新视图控制器中的所有值,并删除“下载...”视图和/或微调器。这将显示新视图,但在数据进入之前不完整,然后使用数据进行更新,并告知用户必须等待的视图将被删除。
答案 1 :(得分:2)
在等待网络访问时阻止主线程是您在iOS应用中从未做过的十大事情列表。
我不确定为什么你认为你需要阻止主线程。通常情况下,您在相关视图中有一个加载微调器或某个指示符,在网络调用完成时会将其删除。您可以使用上面代码中的comlletion块将任何信息传递到目标视图控制器,或者您可以将网络代码移动到另一个视图控制器中,并在准备segue时传递参数。