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

Most likely you have your format statement wrong.

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

Make sure that someTimeDependentValue is a float. If it is an int it will likely get formatted to 0.0000.

Here's a repo showing a working version of what you describe. Whatever is wrong is not related to the threading.

于 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 に答える