2011-03-19 38 views
0

我有一个从Web服务加载数据的小iPhone应用程序。为了确保在加载数据时没有任何问题,我通过应用程序创建了一个半透明视图,并使用CFRunloopRun()等待所有数据在后台加载。这是该代码:如何在后台加载数据时使用UI事件

 self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; 

    // Now show an animation 
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    UIView *window = [[UIApplication sharedApplication] keyWindow]; 
    UIView *shield = [[UIView alloc] initWithFrame:window.bounds]; 
    shield.backgroundColor = [UIColor blackColor]; 
    shield.alpha = 0.5f; 
    [window addSubview:shield]; 
    spinner.center = shield.center; 
    [shield addSubview:spinner]; 
    spinner.hidden = NO; 
    NSLog(@"JCL.callServerWithRequest(), spinner view: %@, shield view: %@, window: %@", spinner, shield, window); 
    [spinner startAnimating]; 

    // Hand over to the Runnloop to wait 
    CFRunLoopRun(); 

    [spinner stopAnimating]; 
    [spinner removeFromSuperview]; 
    [spinner release]; 
    [shield removeFromSuperview]; 
    [shield release]; 

这工作得很好,只是一个按钮点击任何地方被加载后打得如此,如果用户点击下载按钮两次,他会做两次下载以及。

任何想法如何在屏蔽被移除之前消耗UI事件。

谢谢 - 安迪

+0

什么视图是按钮? – MCannon 2011-03-19 01:57:23

回答

0

尝试一下,不要搞乱runloops。我怀疑UI事件会进入窗口的正常循环,但在您的自定义循环返回之前不会被处理,此时“屏蔽”视图不再存在以便捕获它们。如果将防护罩放在适当的位置,然后让主要的防滑圈处理东西,那么防护罩应该像平常一样抓住它们。

+0

我想过这个,但需要对代码进行一些更改。所以我想知道当我尝试在后台线程(从Web服务加载数据的那个线程)中更新UI时会发生什么。是否有任何问题,因为这是在另一个线程中完成的? – 2011-03-19 05:25:15

+0

是的,UI调用只能在主线程上完成。从后台线程使用NSObject的'performSelectorOnMainThread:withObject:waitUntilDone:'来调用主线程上的方法。 – Anomie 2011-03-19 15:41:39

0

感谢Anomie我终于在没有CFRunLoopRun()的情况下试过了,这很困难,因为执行分为两部分: - 调用和通过回调返回结果。但后来我开始在自己的脚下开枪,因为我试图阻止返回的线程,以减慢执行的速度,因为它在主线程中再次执行,因此无法正常工作。

最终我放慢了Web服务的速度,然后一切按预期工作。

相关问题