0

我已经阅读了我能找到的所有相关问题,但我仍然陷入困境,所以我希望有人能发现我的推理错误。

我正在尝试定期更新一些 UIView。为简单起见,我将代码简化为以下内容。摘要:在 viewDidLoad 中,我在一个新的后台线程上调用了一个方法。该方法调用主线程上的一个方法,该方法应该更新一些 UILabel。代码似乎工作正常:后台线程不是主线程,调用 UILabel 更新的方法在主线程上。在代码中:

在 viewDidLoad 中:

[self performSelectorInBackground:@selector(updateMeters) withObject:self];

这将创建一个新的后台线程。我的方法 updateMeters(为简单起见)现在看起来像这样:

if ([NSThread isMainThread]) { //this evaluates to FALSE, as it's supposed to
    NSLog(@"Running on main, that's wrong!");
}
while (i < 10) {
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
//The code below yields the same result
//        dispatch_async(dispatch_get_main_queue(), ^{
//            [self updateUI];
//        });
    [NSThread sleepForTimeInterval: 1.05];
    ++i;
}

最后,updateUI 就是这样做的:

if ([NSThread isMainThread]) { //Evaluates to TRUE; it's indeed on the main thread!
    NSLog(@"main thread!");
} else {
    NSLog(@"not main thread!");
}
NSLog(@"%f", someTimeDependentValue); //logs the value I want to update to the screen
label.text = [NSString stringWithFormat:@"%f", someTimeDependentValue]; //does not update

据我所知,这应该有效。但不幸的是,它没有......被注释掉dispatch_async()的结果是一样的。

4

2 回答 2

1

很可能您的格式声明错误。

label.text = [NSString stringWithFormat:@"%f", someTimeDependentValue];

确保 someTimeDependentValue 是一个浮点数。如果它是一个 int,它可能会被格式化为 0.0000。

这是一个显示您所描述内容的工作版本的存储库。任何错误都与线程无关。

于 2012-03-02T15:54:33.247 回答
0

为了扩展我的评论,这里有一个使用 NSTimer 可能最好实现的场景:

-(void)viewDidLoad
{
       NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:<number of seconds per tick> target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];
}

-(void)timerTick:(id)sender
{
      label.text = ...;
}

我在我的项目中广泛使用了一种更精细的方法。这就是引擎的概念。

我会有一个使用计时器在后台运行的引擎。在关键时刻,它会使用/NSNotificationCenter在主线程上发布通知,然后您的任何一个视图都可以通过更新其 UI 来订阅和处理该通知。dispatch_asyncdispatch_get_main_thread()

于 2012-03-02T16:00:22.793 回答