2014-11-05 62 views
1

該應用程序在iOS 7中正常工作,但是當我瘋狂切換到iOS 8時,該應用程序無法正常工作。在調試模式下,調用應用程序中的NSThread detachNewThreadSelector函數以在前臺創建一個忙框,以防止用戶訪問。主線程繼續並調用Web服務來檢索數據。一旦收到數據,就會調用另一個detachNewThreadSelector來關閉第一個線程。iOS 8中的NSThread detachNewThreadSelector

在iOS 8中,當我在調試模式下進入時,在到達detachNewThreadSelector後,沒有任何反應。第一個線程中的代碼不會被執行。主線程繼續打開並調用Web服務來檢索數據。一旦收到數據,第二個detachNewThreadSelector就會被覆蓋,但代碼不會被執行,直到它到達viewdidload函數的末尾。

dismissActivityIndi​​cator的代碼在CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION中執行,該代碼將生成'嘗試從視圖控制器中消除「錯誤。然後進入__CFRunLoopDoSources0,然後在__CFRunLoopRun中執行showActivityIndi​​cator的代碼。這會導致應用程序創建一個忙框,無法解除它,因爲dismissActivityIndi​​cator已經被執行。不太確定爲什麼這些函數被反向調用並在viewdidload函數結束時調用。

該項目傳遞給我,所以我不熟悉如何生成彈出視圖來阻止主線程,直到數據從源獲取。我需要快速修復或解釋發生的問題以修復iOS 8問題。

-(void)callService{ 
    [NSThread detachNewThreadSelector: @selector(showActivityIndicator) toTarget:self withObject:NULL]; 
sleep(1); 

    //call web service 

    [NSThread detachNewThreadSelector: @selector(dismissActivityIndicator) toTarget:self withObject:NULL]; 
} 


-(void)showActivityIndicator{ 
    UISplitViewController *splitVC = [[self navigationController] splitViewController]; 
    UINavigationController *detailVC = [[splitVC viewControllers] objectAtIndex:1]; 

    activityIndicatorVC = [[ActivityIndicatorVC alloc] init]; 
    [activityIndicatorVC setModalTransitionStyle:UIModalTransitionStyleCoverVertical]; 
    [activityIndicatorVC setModalPresentationStyle:UIModalPresentationFormSheet]; 

    [detailVC presentViewController:activityIndicatorVC animated:NO completion: nil]; 
    CGRect r2 = CGRectMake(detailVC.view.bounds.size.width/2 - 80, 
         detailVC.view.bounds.size.height/2 - 150, 160, 160); 
    r2 = [detailVC.view convertRect:r2 toView:activityIndicatorVC.view.superview.superview]; 
    activityIndicatorVC.view.superview.frame = r2; 
} 

-(void)dismissActivityIndicator{ 
    UISplitViewController *splitVC = [[self navigationController] splitViewController]; 
    UINavigationController *detailVC = [[splitVC viewControllers] objectAtIndex:1]; 
    [detailVC dismissModalViewControllerAnimated:NO]; 
} 

回答

2

主線程繼續進行,並調用Web服務來獲取數據

我如何生成一個彈出以阻塞主線程,直到數據從源獲取陌生。

不要在主線上做這些事情!像這樣的問題解決自己,如果你只使用主線程的UI,並且肯定永遠不會等待其他東西。

你也正在做sleep(1);在(大概)主線程,這是類似的原因不好。此外,您幾乎不需要使用sleep以適當的設計。使用sleep是一個很好的指示器,您不會理解線程。

現在到答案(也許)

我難以理解爲什麼要分離showActivityIndicatordismissActivityIndicator自己的線程。除了主線程之外的任何UI操作通常是不僅是未定義的行爲(不是線程安全的),而是一般的壞主意。

其次,你將它們分離到不同的線程,所以它們都同時運行。顯然這是而不是你想要什麼。需要在webservice調用返回之後運行dismissActivityIndicator,而不是之前。您從代碼中刪除了showActivityIndicatordismissActivityIndicator之間的實際呼叫,所以誰知道這裏實際發生了什麼;我只是猜測。

它應該是在自己的線程上執行的web服務調用。然後,您將利用完成處理程序(在主線程上)來解除任何UI元素需要解僱的問題。

+0

此函數是一個更新函數,用於調用應用程序運行所必需的數據。這就是爲什麼在接收數據之前主線程阻塞的原因。 – 2014-11-06 14:31:16

+0

@vily *不是*阻止主線程的好理由。我想不出有任何理由阻止主線程。 – 2014-11-06 14:38:20

+0

主要功能是同時運行showActivityIndi​​cator和主線程,直到檢索到大量數據爲止,並且dismissActivityIndi​​cator將在完成Web服務調用後移除第一個線程,以使應用程序可用,這適用於iOS 7。函數是一個初始化/更新函數。在數據初始化之前,該應用程序無法工作,或者如果在工作日開始時沒有更新,則不會顯示正確的數據。之所以必須這樣做,是因爲該應用程序是爲了在沒有互聯網連接的情況下使用 – 2014-11-06 15:01:09