2012-06-21 20 views
2

我正試圖從我的視圖的負載上執行從互聯網上獲取數據。爲了不滯後UI,我使用等到後臺選擇器完成後調用新方法

[self performSelectorInBackground:@selector(alertThreadMethod) withObject:nil]; 

執行HTML下載和解析,它檢查是否有在線警報。然而,爲了在視圖上顯示信息,iOS說我需要使用主線程。所以我之後調用顯示代碼:

[self performSelectorInBackground:@selector(alertThreadMethod) withObject:nil]; 
[self loadAlert]; 

在這樣做,實際上[self loadAlert];在後臺選擇(這是更快)之前運行。因此,它沒有背景中的選擇器應該提供的信息。

如何確保[self loadAlert];之後運行?還是有更好的方法來做到這一點?

回答

5

您可以移動loadAlert調用到alertThreadMethod或使用Grand Central Dispatch串行隊列,例如,

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL); 
dispatch_async(queue, ^{ 
    [self alertThreadMethod]; 
    [self loadAlert]; 
}); 
dispatch_release(queue); 

或者,如果loadAlert正在更新UI,因爲你在主隊列做UI更新,你會這樣做:

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL); 
dispatch_async(queue, ^{ 
    [self alertThreadMethod]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self loadAlert]; 
    }); 
}); 
dispatch_release(queue); 

順便說一句,如果你只是在做這個任務的背景下,而不是創建自己的串行隊列,你可能只是使用現有的後臺隊列中的一個。如果你需要序列性質的話,你只需要創建一個隊列(即你將會進行大量的dispatch_async調用,並且你不能讓它們同時運行)。但是,在這個簡單的情況下,這可能是甚至有點更有效率,繞過創建和串行隊列的釋放:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(queue, ^{ 
    [self alertThreadMethod]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self loadAlert]; 
    }); 
}); 
+0

如果我將它移動到alertThreadMethod中,它會在後臺調用並出現錯誤(它不允許在後臺調用)。我會研究這些串行隊列。 – DGund

+0

@DevinGund查看代碼示例,其中展示瞭如何將UI更新提交回主隊列。 – Rob

+0

看起來像代碼示例#3(或2)將最適合我。我可以直接將此代碼複製到我的應用程序中嗎?我對調度隊伍不熟悉,我不確定是否需要先輸入任何東西。 – DGund

1

在你alertThreadMethod,你有你的信息後,調用該方法performSelectorOnMainThread:withObject:waitUntilDone :並將選擇器傳遞給您的loadAlert方法。

-(void)alertThreadMethod 
{ 
    // get your information here 

    performSelectorOnMainThread:@selector(loadAlert) withObject:nil waitUntilDone:NO 
}