2015-04-03 38 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; 
    } 
}