我有一个名为“刷新数据”的UIBarButtonItem。当用户单击它时,应用程序应刷新其数据。在该按钮单击上发生的是启动Web服务并带来xml数据,它们的订单数量为30000-40000。因此,为了防止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秒后,该框消失,动画开始显示活动指示器。我的目标是获得这样的东西。 1.用户点击刷新数据按钮。 2.Alert视图显示。 3.用户单击确定。 4.Alert框消失,后台线程立即开始工作,我看到活动指示器工作/动画。
用户将知道在活动指示器动画时等待。那么如何在用户点击“确定”后立即启动动画,并且警报视图确定不会变黑。我清楚了吗?如果您需要更多信息,请询问。感谢
编辑:当第一次加载当天时,此屏幕有一个后台线程正在处理它。在此之前有一个屏幕。在它上面我有继续按钮并点击它启动背景线程,它完全像这一样在这里。我不会杀死它或任何东西。
编辑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");
}
答案 0 :(得分:0)
尝试更改
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) {
答案 1 :(得分:0)
使用alertView:didDismissWithButtonIndex:
代替alertView:clickedButtonAtIndex:
。这样,在调用代码时,警报就已被解除。
问题 - 为什么要打扰警报视图?用户知道他们点击了“刷新”图标。您已经显示了活动指示符,并且警报不会让用户有机会取消刷新。
更新:对dispatch_async的调用似乎有点过时了。试试这个:
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");
}
});
答案 2 :(得分:0)
添加一些NSLog可能有助于查看它挂起的位置,并停止活动指示器以查看是否由于调度而导致整个挂起。
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)队列由于某种原因而被停止,这导致事物看起来挂起。因为它已停止,即使您已告诉他们开始设置动画,刷新活动指示器等内容也不会生成动画。并且请记住,您无法在异步中更新UI,因此不应使用secondMOC来导致任何表重新加载数据和[self getAllCustomerValues];不应该做任何UI的东西。
答案 3 :(得分:0)
我们使用MBProgressHUD(https://github.com/jdg/MBProgressHUD),这使得这种UI通知变得容易。通常,您提供一个可以检查 atomic BOOL值的方法。当您放置HUD时设置BOOL,当后台进程完成时清除BOOL并且HUD将自动消失。
答案 4 :(得分:0)
你说这是在后台线程上发生的一切 - 确保你在主线程上加载UIAlertView:
//[alert show];
[alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:FALSE];
这可能会解决问题。您的异步调用实际上发生在运行循环中的当前线程上(因为它是后台线程),阻止您尝试显示的警报视图(在同一个运行循环中)。