在AFNetworking后台线程完成之前,有没有办法阻止iOS中的主线程?

时间:2014-09-24 18:11:02

标签: ios objective-c multithreading afnetworking-2

我正在使用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

2 个答案:

答案 0 :(得分:3)

你真的不想阻止线程。使用顶部视图打开新的视图控制器,该视图只有一个标记为“正在下载...”(或运行微调器)。在下载的完成块中,调用主线程[self performSelectorOnMainThread ...]上的例程,该例程更新新视图控制器中的所有值,并删除“下载...”视图和/或微调器。这将显示新视图,但在数据进入之前不完整,然后使用数据进行更新,并告知用户必须等待的视图将被删除。

答案 1 :(得分:2)

在等待网络访问时阻止主线程是您在iOS应用中从未做过的十大事情列表。

我不确定为什么你认为你需要阻止主线程。通常情况下,您在相关视图中有一个加载微调器或某个指示符,在网络调用完成时会将其删除。您可以使用上面代码中的comlletion块将任何信息传递到目标视图控制器,或者您可以将网络代码移动到另一个视图控制器中,并在准备segue时传递参数。