Я прочитал все связанные вопросы, которые смог найти, но все еще застрял, поэтому я надеюсь, что кто-то заметит мою ошибку в рассуждениях.
Я пытаюсь периодически обновлять некоторые 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()
дает тот же результат.