2011-05-29 32 views
2

我已经成立了一个标签布局我的iPhone应用程序的计算/处理数据,我想执行一些相当激烈计算(可能需要几秒钟才能获得结果),当用户选择一个的选项卡。使用UIAlertView中等待

最初,它会出现在执行数字运算时iphone会挂在原始选项卡上。

我试着添加一个UIAlertView作为一些眼睛糖果,但我渐渐灰暗了几秒钟,然后计算完成后,快速出现/视图消失。我想看到的是UIAlertView中出现/动画当用户触摸选项卡,然后消失,一旦计算完成

- (void)viewDidAppear:(BOOL)animated 
{  


    UIAlertView *baseAlert = [[[UIAlertView alloc] initWithTitle:@"Calculating" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil]autorelease]; 
    [baseAlert show]; 
    UIActivityIndicatorView *aiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    aiv.center = CGPointMake(baseAlert.bounds.size.width /2.0f, baseAlert.bounds.size.height - 40.0f); 
    [aiv startAnimating]; 
    [baseAlert addSubview:aiv]; 
    [aiv release]; 


/*** calculation and display routines***/ 


    [baseAlert dismissWithClickedButtonIndex:0 animated:YES]; 
} 

我已经看到this post,但我似乎无法弄清楚如何将其应用于我的案例。

回答

6

解决此问题的最简单方法是使用块;首先进度计算使用第一块单独的线程,完成后通过块出动主线程关闭提醒观点:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{ 

// Do calculations 


dispatch_async(dispatch_get_main_queue(),^
         { 
          [baseAlert dismissWithClickedButtonIndex:0 animated:YES]; 
         }); 
}); 
+0

那是光荣的!谢谢 – Rasman 2011-05-29 21:43:20

0

可能发生的情况是,您正在执行的“密集计算”正在与您调用UIAlertView的位置相同的线程中运行。设置一个委托UIAlertView中就设置了一个单独的线程,这样你就不需要担心竞争,以及是否会UIAlertView中计算前露面。

另外,使用UIAlertView中是一个相当重手的方式 - 也许当你紧缩一些数字,你可以使用一些其他的界面元素来显示进度,而不是渲染应用无用的?

4

您需要了解事件循环的作品。当你调用[baseAlert show],警报视图添加到视图层次,但实际上并没有吸引到屏幕上,直到当前的代码块结束和控制返回到事件循环。通过询问警报视图来显示后立即做你的计算,你是防止警报从不断出现。

这有点像写一封信,告诉你打算粉刷你家的人,花一个星期画你的房子,然后写另一封信,说你已经做到了,并THEN采取字母和在拖放邮箱同时交付。

如果你有一个昂贵的计算,在iOS 4和更高版本中处理它的最简单方法是将一个代码块放入一个调度队列中,这样工作将在后台线程中完成,而主线程可以仍然更新屏幕并响应手指点击。

[baseAlert show]; 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{ 
    // we're on a secondary thread, do expensive computation here 
    // when we're done, we schedule another block to run on the main thread 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // this code is back on the main thread, where it's safe to mess with the GUI 
     [baseAlert dismissWithClickedButtonIndex:0 animated:YES]; 
    }); 
}); 
+0

欣赏解释 – Rasman 2011-05-29 21:43:15