2015-04-03 55 views
0

我正在嘗試調整UILabel以適應裏面的文本。事情看起來很簡單,但這裏是我在做什麼:iOS可能的線程問題

[GKTurnBasedMatch loadMatchWithID:[matchReceived matchID] withCompletionHandler:^(GKTurnBasedMatch *updatedMatch, NSError *error){ 

     NSPropertyListFormat plf; 
     NSMutableDictionary* gameData = [NSPropertyListSerialization propertyListWithData:updatedMatch.matchData options:NSPropertyListMutableContainersAndLeaves format:&plf error:nil]; 

     myLabel.text = [gameData objectForKey:@"DictionaryText"]; 
     [myLabel sizeToFit]; 
    } 

如果我把文本的設置添加,調整大小根據需要調整myLabel適應一個performSelector用幾秒鐘的延遲。但是我需要在遊戲數據加載後立即更新標籤。

我試過對MainThread執行操作,但沒有奏效。

任何想法?

+0

正如我在下面回答的評論提到,建成塊總是叫上主隊列,但實際的請求加載匹配是在後臺完成的,這意味着在將控制權交給其完成處理程序之前,該方法需要一點時間才能執行。鑑於* request *需要時間,不一定是UI更新,可能和選項是在代碼的早期調用此調用,或者添加某種依賴關係,或者使用佔位符,直到數據加載 – 2015-04-03 18:21:48

回答

2

首先關閉任何與UI交互的代碼必須在主線程上執行。所以很可能你的問題的一部分來自不在主線程中。我已經看到由後臺線程上的UI代碼導致的各種奇怪的行爲。

一旦您在主線程上擁有它,您就可以開始診斷真正的問題。很難說出什麼問題,但有一點可以想到,這可能是一個與約束有關的問題。

+0

但是這個類方法聲明完成處理程序總是在主線程上調用 – 2015-04-03 18:10:08

0

所有UI代碼必須在主線程中運行。因此,如何檢查,代碼運行其中:

if ([NSThread isMainThread]) { /*main*/ } else { /*not main*/ } 

如何強迫任何代碼在主線程中運行:

dispatch_async(dispatch_get_main_queue(), ^{ // serial, UI thread 
    .... 
}); 

最後一件事是,以確保您的變量可以在裏面塊被修改。使用__block局部變量和使用弱引用self對象屬性:

__weak typeof(self) weakSelf = self; 
__block BOOL success = NO; 
[myOb doBlock:^(id item) 
{ 
    __strong typeof(self) strongSelf = weakSelf; 
    if (strongSelf) 
    { 
     strongSelf.myLabel = @"changed"; 
     success = YES; 
    } 
}