2011-03-19 41 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服務的速度,然後一切按預期工作。