2012-01-03 45 views
2

如何使用隊列中的值更新GUI元素? 如果我使用異步隊列構造,textlable不會更新。 這裏是我使用的代碼示例:從異步回調(dispatch_queue)更新UI組件

- (IBAction)dbSizeButton:(id)sender { 
    dispatch_queue_t getDbSize = dispatch_queue_create("getDbSize", NULL); 
    dispatch_async(getDbSize, ^(void) 
    { 
     [_dbsizeLable setText:[dbmanager getDbSize]]; 
    }); 

    dispatch_release(getDbSize); 
} 

謝謝。

+0

你嘗試'performSelectorOnMainThread:withObject:waitUntilDone:'? – Hejazi 2012-01-03 20:27:18

回答

8

正如@MarkGranoff所說,所有的UI都需要在主線程上處理。你可以用performSelectorOnMainThread做到這一點,但與GCD它會是這樣的:

- (IBAction)dbSizeButton:(id)sender { 

    dispatch_queue_t getDbSize = dispatch_queue_create("getDbSize", NULL); 
    dispatch_queue_t main = dispatch_get_main_queue(); 
    dispatch_async(getDbSize, ^(void) 
    { 
     dispatch_async(main, ^{ 
      [_dbsizeLable setText:[dbmanager getDbSize]]; 
     }); 
    }); 

    // release 
} 
+1

除了你可能會想要私人隊列上發生-getDbSize,而不是主隊列... – 2012-01-03 21:45:51

+0

@Catfish_Man:但不是getDbSize私人隊列? – JohnK 2013-05-14 20:10:37

+0

它不在getDbSize隊列上發生。它發生在主隊列上運行的dispatch_async塊中。您需要它在第一個dispatch_async中,但在第二個之外。 – 2013-05-14 20:32:13

2

必須在主線程上執行任何UI更新。因此,您的代碼需要修改爲使用主調度隊列,而不是您自己創建的隊列。或者,任何performSelectorOnMainThread方法都可以。 (但GCD是最近的路要走!)