2013-11-01 24 views
0

在我的iOS應用程序中,用戶可以打開從磁盤加載的項目。這需要一些時間,所以我展示了我的自定義加載視圖,它是UIView的子類。這個加載視圖有一個像進度條一樣的標籤。我試圖不斷更新它的價值。從主隊列的回調更新UIView上的UILabel

這是第一種方法(我簡化了我的代碼位):

// in view controller, which has projects list 

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

[projectsManager loadProject:project statusChangedCallback: ^(NSString* status){ 
    self.loadingDialog.progressString = status; 
}]; 

[self closeLoading]; 

// in ProjectsManager 

-(void) loadProject:(NSString*)project statusChangedCallback:(void(^)(NSString* status))callback 
{ 
    callback(@"Loading some data..."); 
    [self loadSomeDataFrom:project]; 

    callback(@"Loading other data..."); 
    [self loadOtherDataFrom:project]; 
} 

這種方法是行不通的(的UILabel沒有更新),因爲我多次從主隊列中的一個循環週期進行更新。我也嘗試了不同的方法,如:

[projectsManager loadProject:project statusChangedCallback: ^(NSString* status){ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     self.loadingDialog.progressString = status; 
    }); 
}]; 

但在後臺標籤這樣的更新,因爲同樣的原因不太可能的工作 - 主循環停止。我想把我的所有項目加載到後臺線程中,所以主循環不會受到影響,但這是不可能的,因爲項目加載與一些只能在主線程中執行的OpenGL紋理緊密相關。

我也試着發送-setNeedsDisplay查看,但這並沒有工作過。

那麼,怎樣才能讓我的標籤更新,而主隊列忙?也許,我需要改變呈現加載視圖機制的體系結構?

回答

0

由於您使用的是後臺隊列,因此值不會更新,並且無法在主線程旁邊的任何線程中更新UI,dispatch_get_global_queue仍然使用後臺線程,對UI中的任何更改均使用dispatch_get_main_queue

嘗試:

dispatch_async(dispatch_get_main_queue()^ { self.loadingDialog.progressString =狀態; })

+0

試過了也沒用...此代碼可能與沒有'dispatch_async'幾乎相同,因爲所有操作都在主隊列中執行。 – medvedNick