Я сделал полное объяснение с примером кода, используя executeSelectOnBackground или GCD здесь:
GCD, Потоки, Поток программы и Обновление пользовательского интерфейса
Вот часть кода примераэтот пост (минус его конкретные проблемы:
executeSelectorInBackground Пример:
В этом фрагменте у меня есть кнопка, которая вызывает долгосрочную работу, метка состояния и ядобавлен ползунок, чтобы показать, что я могу переместить ползунок, пока работа bg завершена.
// on click of button
- (IBAction)doWork:(id)sender
{
[[self feedbackLabel] setText:@"Working ..."];
[[self doWorkButton] setEnabled:NO];
[self performSelectorInBackground:@selector(performLongRunningWork:) withObject:nil];
}
- (void)performLongRunningWork:(id)obj
{
// simulate 5 seconds of work
// I added a slider to the form - I can slide it back and forth during the 5 sec.
sleep(5);
[self performSelectorOnMainThread:@selector(workDone:) withObject:nil waitUntilDone:YES];
}
- (void)workDone:(id)obj
{
[[self feedbackLabel] setText:@"Done ..."];
[[self doWorkButton] setEnabled:YES];
}
Образец GCD:
// on click of button
- (IBAction)doWork:(id)sender
{
[[self feedbackLabel] setText:@"Working ..."];
[[self doWorkButton] setEnabled:NO];
// async queue for bg work
// main queue for updating ui on main thread
dispatch_queue_t queue = dispatch_queue_create("com.sample", 0);
dispatch_queue_t main = dispatch_get_main_queue();
// do the long running work in bg async queue
// within that, call to update UI on main thread.
dispatch_async(queue,
^{
[self performLongRunningWork];
dispatch_async(main, ^{ [self workDone]; });
});
}
- (void)performLongRunningWork
{
// simulate 5 seconds of work
// I added a slider to the form - I can slide it back and forth during the 5 sec.
sleep(5);
}
- (void)workDone
{
[[self feedbackLabel] setText:@"Done ..."];
[[self doWorkButton] setEnabled:YES];
}