在后台线程正在加载数据时挂起UIAlertview

我有一个名为“刷新数据”的UIBarButtonItem。 当用户点击它时,应用程序应刷新其数据。 点击这个button会发生什么事情,Web服务被启动,XML数据被带入,它们的顺序为30000-40000条logging。 所以为了防止UI挂起我写了一个后台线程,并在那里加载。

- (void)refreshDataAction { NSLog(@"Refresh Data"); //Put up an alert box indicating user to wait while data is loading. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Data is Loading" message:@"Please wait while data is being refreshed." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; alert.tag = 10; [alert show]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { NSLog(@"hit in clickedbuttonatindex alertview at 259"); self.refreshActIndicator.hidden = NO; [self.refreshActIndicator startAnimating]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { [self getAllCustomerValues]; NSError *nwerror = nil; if (![self.secondMOC save:&nwerror]) { NSLog(@"209 Failed to save second MOC"); } else { //NSLog(@"saved success"); } }); } 

就像你可以看到显示的警报视图。 我点击确定,框中仍然存在“变黑”,并挂在屏幕上。 然后7-8秒钟后,框消失,animation开始animation指示器。 我的目标是得到这样的东西。 1.用户点击刷新数据button。 2.Alert视图出现。 3.用户点击确定。 4.Alert框消失,立即后台线程开始工作,我看到活动指标工作/animation。

用户将知道等待,而活动指标是animation。 那么如何让应用程序在用户点击“OK”后立即开始animation,并且alertview不会被黑掉。 我清楚了吗?如果您需要更多信息,请询问。 谢谢

编辑:这个屏幕有一个后台线程工作,当它加载第一次的那一天。 这之前有一个屏幕。 在它上面,我继续button,然后单击它,启动后台线程,就像这个一样在这里完成相同的事情。我不杀它或任何东西。

编辑2:

  - (void)refreshDataAction { NSLog(@"Refresh Data"); self.txtCustomerSearch.text =@""; [self cleanUPPreviousLabels]; //Put up an alert box indicating user to wait while data is loading. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Data is Loading" message:@"Please wait while data is being refreshed." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; //alert.tag = 10; //[alert show]; [alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:FALSE]; NSLog(@"hit in willpresenet alertview at 221"); self.refreshActIndicator.hidden = NO; [self.refreshActIndicator startAnimating]; NSLog(@"Dispatching"); //Disable the view and all the other controls self.txtCustomerSearch.userInteractionEnabled =NO; self.txtCustomerSearch.enabled =NO; self.btnSearch.enabled =NO; self.btnSearch.userInteractionEnabled = NO; self.scrollView.userInteractionEnabled = NO; //self.view.userInteractionEnabled =NO; self.chkButton.enabled = NO; [self deletePreviousValues]; dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ NSLog(@"Getting customer values"); [self getAllCustomerValues]; NSLog(@"Got customer values"); NSError *nwerror = nil; if (![self.secondMOC save:&nwerror]) { NSLog(@"209 Failed to save second MOC"); } else { //NSLog(@"saved success"); } self.txtCustomerSearch.userInteractionEnabled = YES; self.txtCustomerSearch.enabled =YES; self.btnSearch.enabled =YES; self.btnSearch.userInteractionEnabled = YES; self.scrollView.userInteractionEnabled = YES; self.view.userInteractionEnabled =YES; self.chkButton.enabled = YES; [self.refreshActIndicator stopAnimating]; NSLog(@"Saved"); }); NSLog(@"Dispatched"); 

}

尝试改变

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { 

到后台优先

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, (unsigned long)NULL), ^(void) { 

使用alertView:didDismissWithButtonIndex:而不是alertView:didDismissWithButtonIndex: alertView:clickedButtonAtIndex: 这样,当您的代码被调用时,警报已经被解除。

问题 – 为什么要打扰警报视图? 用户知道他们点击了“刷新”图标。 您已经显示一个活动指示器,并且警报不会让用户有机会取消刷新。

更新:调用dispatch_async似乎有点closures。 尝试这个:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self getAllCustomerValues]; NSError *nwerror = nil; if (![self.secondMOC save:&nwerror]) { NSLog(@"209 Failed to save second MOC"); } else { //NSLog(@"saved success"); } }); 

这可能有助于添加一些NSLogs来查看挂起的位置,并停止活动指示器以查看是否由于发送而发生整个挂起。

  NSLog(@"hit in clickedbuttonatindex alertview at 259"); self.refreshActIndicator.hidden = NO; [self.refreshActIndicator startAnimating]; NSLog(@"Dispatching"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { NSLog(@"Getting customer values"); [self getAllCustomerValues]; NSLog(@"Got customer values"); NSError *nwerror = nil; if (![self.secondMOC save:&nwerror]) { NSLog(@"209 Failed to save second MOC"); } else { //NSLog(@"saved success"); } [self.refreshActIndicator stopAnimating]; NSLog(@"Saved"); }); NSLog(@"Dispatched"); 

发生什么事是因为某种原因主要(UI)队列被停止,这导致东西似乎挂起。 因为它被停止了,所以即使你告诉他们开始animation,刷新活动指示器也不会生成animation。 请记住,您无法在asynchronous中更新UI,因此不应使用secondMOC来使任何表重新载入数据,并且[self getAllCustomerValues]; 不应该做任何UI的东西。

我们使用MBProgressHUD( https://github.com/jdg/MBProgressHUD ),这使得这种UI通知变得简单。 通常你提供一个可以检查一个BOOL primefaces值的方法。 放置HUD时设置BOOL,当后台进程完成时,清除BOOL,HUD将自动消失。

你说这一切都发生在后台线程上 – 确保你在主线程中加载了UIAlertView:

 //[alert show]; [alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:FALSE]; 

这可能会解决这个问题。 您的asynchronous调用实际上是在运行循环中的当前线程上发生的(因为它是后台线程)阻塞了您试图显示的警报视图(在同一个运行循环中)。