Multithreading 生成并加载UITableView时,无法显示MBProgressHUD加载掩码

Multithreading 生成并加载UITableView时,无法显示MBProgressHUD加载掩码,multithreading,uitableview,asynchronous,grand-central-dispatch,mbprogresshud,Multithreading,Uitableview,Asynchronous,Grand Central Dispatch,Mbprogresshud,我有一个TabBarController,它包含3个TabBarItem。单击第二个选项卡项时,将生成并加载UITableView。加载表需要足够长的时间,没有任何动作,并且用户有礼貌地指示下一个场景正在进行中。然而,我一直无法让这项工作。我曾尝试使用GCD实现加载掩码,但它仅在加载表后显示。过了20秒,情况就不太好了 我尝试了以下代码来响应TabBarItem单击: [MBProgressHUD showHUDAddedTo:self.navigationController.view ani

我有一个TabBarController,它包含3个TabBarItem。单击第二个选项卡项时,将生成并加载UITableView。加载表需要足够长的时间,没有任何动作,并且用户有礼貌地指示下一个场景正在进行中。然而,我一直无法让这项工作。我曾尝试使用GCD实现加载掩码,但它仅在加载表后显示。过了20秒,情况就不太好了

我尝试了以下代码来响应TabBarItem单击:

[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
               ^{
                   dispatch_async(dispatch_get_main_queue(), ^{


                       NSLog(@"dispatch");
                       [self.navigationController.view.superview addSubview:HUD];

                       [MBProgressHUD hideHUDForView:viewController.view animated:YES];

                   });



               });
在构建UITableview时,我也尝试过:

   dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

   dispatch_sync(queue, ^{

          UIImage * image = [UIImage imageWithData:imageData];

          dispatch_sync(dispatch_get_main_queue(), ^{

          [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];

          [cell.merchItemImageView setImage:image];

          NSLog(@"shortDesc==%@",merchitem.itemName);
          NSLog(@"itemPrice==%@",merchitem.itemPrice);

          cell.merchItemShortDesc.text =  [NSString stringWithFormat:@"%@",merchitem.itemName];
         cell.merchItemPrice.text = [NSString stringWithFormat:@"$%@",merchitem.itemPrice];



});

});

尝试在表构建/加载代码中找到它开始严重阻塞用户界面的地方,并将代码移动到辅助方法。在原始方法调用
MBProgressHUD
结束时,在第零次延迟后,将选择器排入当前运行循环的队列。它首先运行挂起的UI操作(包括MBProgressHUD的对话框),然后运行阻塞代码。我对a执行类似的操作,首先显示
SVProgressHUD
警报,然后执行无响应任务

因此,如果您的代码如下所示:

step1;
step2;
really_long_step3;
你可以像这样分开它

    step1;
    [MBProgressHUD updates];
    [self performSelector:@selector(do_remaining_steps)
        withObject:nil afterDelay:0];
}
- (void)do_remaining_steps
{
    step2;
    really_long_step3;
    [MBProgressHUD reportSomeSuccessScreen];
}

这里的诀窍是在选项卡切换和视图创建层次结构中找到代码块的位置,以及如何拆分代码块,以便在长时间运行的加载之前进行UI更新。希望这一切都发生在您的
-(void)viewDidLoad
方法中,因此
viewDidLoad
将在更新HUD之前将
do_剩余步骤
选择器排到最后。

感谢@Grzegorz的响应。然而,我无法理解这一点。实际上,在点击tabbaritem后,会在故事板上进行转换。上述代码分别通过以下方法实现——(void)tabBarController:(UITabBarController*)tabBarController didSelectViewController:(UIViewController*)viewController和-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath。我试着按照你的建议分解工作,但是我不知道如何做,因为正在构建表单元格。你需要找到tableview代码中到底是什么花费了这么长的时间。既然你说需要20秒,我会在
loadView
viewDidLoad
和在控制器生命周期内调用的其他方法中设置一个断点来解决这个问题。您可以尝试的另一件事是使用“Loading”消息将tableview设置为空,并在第一次调用
ViewDidDisplay
时实际构建单元格。在调用此方法时,“加载”消息应该是可见的。