私は見つけたすべての関連する質問を読みましたが、私はまだ立ち往生しているので、誰かが私の推論の誤りを見つけてくれることを願っています。
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()
結果は同じ結果になります。