0

我有一個名爲「刷新數據」的UIBarButtonItem。當用戶點擊它時,應用程序應刷新其數據。點擊該按鈕時發生的事情是啓動Web服務並引入xml數據,它們的訂單爲30000-40000條記錄。所以爲了防止UI掛起,我寫了一個後臺線程,並在那裏加載。UIAlertview掛在後臺線程正在加載數據

- (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.出現警告視圖。 3.用戶單擊確定。 4.警告框消失,立即後臺線程開始工作,我看到活動指示器工作/動畫。

用戶將知道在活動指示器動畫時等待。那麼,如何在用戶點擊「確定」後立即啓動應用程序,並立即開始動畫製作,並且alertview確定不會變黑。我清楚了嗎?如果您需要更多信息,請詢問。謝謝

編輯:這個屏幕有一個後臺線程在它加載第一次當天的工作。這之前有一個屏幕。在它上面,我繼續按鈕,然後單擊它,啓動後臺線程,這個線程完全相同,就像這個在這裏一樣。我不殺它或任何東西。

編輯2:

- (void)refreshDataAction 
    { 
NSLog(@"Refresh Data"); 
self.txtCustomerSearch.text [email protected]""; 
[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

getAllCustomerValues方法是否同步? – 2013-02-21 19:37:07

+0

@GeorgeSachin。我如何知道? – RookieAppler 2013-02-21 19:41:06

+0

@GeorgeSachin - 由於它在異步隊列上執行,它將異步運行。 – rmaddy 2013-02-21 19:41:52

回答

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) { 
+0

@ Ric.No。改變它,但它仍然是這樣的。警告框變黑,7-8秒後它消失,然後我的活動指標動畫開始。另外我編輯了我的原始文章中的一些信息。請檢查一下。 – RookieAppler 2013-02-21 19:31:48

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"); 
    } 
}); 
+0

那麼,當我沒有警報視圖,然後點擊刷新按鈕,它仍然需要7-8秒來顯示活動指標。所以屏幕凍結了7-8秒沒有發生任何事情。沒有指示器。沒有。我不知道爲什麼它會花費那麼多時間。但是現在我介紹了警報視圖,告訴他們事情正在發生。 – RookieAppler 2013-02-21 19:44:38

+0

您所描述的內容表明數據加載('getAllCustomerValues')確實在主線程上運行。但是,由於您正在後臺隊列上運行該代碼,因此情況並非如此。看到我更新的答案。 – rmaddy 2013-02-21 19:48:21

+0

我改變了你的建議。 dismissWithButtonIndex並在dispatch_async中更改。但只有它那樣。我點擊刷新數據。警報視圖打開。點擊確定關閉。警報框消失了。延遲7-8秒(沒有任何反應),然後指示器開始旋轉/動畫。 – RookieAppler 2013-02-21 19:58:48

0

它可能有助於添加一些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)隊列由於某種原因而停止,這會導致東西似乎掛起。因爲它已停止,所以即使您已告訴他們開始動畫,刷新活動指示器等動畫也不會生成動畫。並且請記住,您無法在async中更新UI,因此不應使用secondMOC來使任何表重新載入數據和[self getAllCustomerValues];不應該做任何UI的東西。

+0

所以在模擬器上的輸出是:點擊clicktonbuttonatindex alertview在259.Dispatching.Getting顧客values.Dispatched.Got顧客values.Saved。在模擬器上也沒有延遲(沒有7-8秒的等待)。在設備上需要時間。 – RookieAppler 2013-02-21 20:08:22

+0

當您在設備上進行調試時 - 「在iOS設備上運行」 - 輸出結果如何? – Ric 2013-02-21 20:12:10

+0

當我連接我的設備到Mac,在xcode我得到「Phani的iPad,iPad 6.1模擬器,iPhone 6.1模擬器」。我選擇「phani的ipad」,然後運行,然後在Xcode中看不到任何輸出。你在說什麼?你能解釋一下嗎?謝謝 – RookieAppler 2013-02-21 20:21:19

0

我們使用MBProgressHUD(https://github.com/jdg/MBProgressHUD),這使得這種UI通知變得簡單。一般來說,你提供了一個被調用的方法,可以檢查一個原子布爾值。放置HUD時設置BOOL,當後臺進程完成時清除BOOL,HUD將自動消失。

0

你說這一切發生在後臺線程 - 確保您加載主線程上UIAlertView中:

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

這可能會解決這個問題。您的異步調用實際上是在運行循環中的當前線程上發生的(因爲它是後臺線程),阻止您試圖顯示的警報視圖(在同一個運行循環中)。

+0

我像你說的那樣編輯我的代碼。它沒有工作。我已經發布了refreshDataAction修改方法。看看並告訴我,如果你發現任何錯誤。謝謝 – RookieAppler 2013-02-22 00:08:46