Выполнение действия кнопки во вторичном потоке - PullRequest
0 голосов
/ 25 ноября 2011

Я хочу знать, почему я не могу запустить действие кнопки во вторичном потоке (см. Ниже код вторичного потока), когда я делаю так, приложение разрывается и показывает мне следующее сообщение об ошибке.

NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(insertdata) object:nil];
[thread start];

void _WebThreadLockFromAnyThread(bool), 0x6a8cfe0: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.

bool _WebTryThreadLock(bool), 0x6a8cfe0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

1   WebThreadLock
2   -[UIFieldEditor setText:andSetCaretSelectionAfterText:]
3   -[UITextField setText:]
4   -[XYZ reset]
5   -[XYZ insertdata]
6   -[NSThread main]
7   __NSThread__main__
8   _pthread_start
9   thread_start

Но когда я меняю поток на основной поток (см. Код основного потока ниже), я не вижу никакого сбоя, и мое приложение работает отлично.Может кто-нибудь объяснить, в чем разница, почему я не могу запустить дополнительный поток действий.

[self performSelectorOnMainThread:@selector(insertdata) withObject:nil waitUntilDone:NO];

Спасибо.

1 Ответ

1 голос
/ 25 ноября 2011

В сообщениях об ошибках указана точная причина:

Получение веб-блокировки из потока, отличного от основного потока или веб-нить. UIKit не должен вызываться из вторичного потока.

Если операция не занимает много времени, нет смысла ее выполнять в фоновом потоке. Если операция действительно занимает много времени, вы должны отделить извлечение данных (или что-то, что занимает много времени) от обновления пользовательского интерфейса, запустить извлечение данных в фоновом режиме, а затем вернуться обратно в основной поток, чтобы обновить UI. Предпочтительно с использованием GCD:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0), ^{
    [self downloadData]; // takes long
    dispatch_async(dispatch_get_main_queue(), ^{
        [self updateUI]; // here you can safely call UIKit
    });
});
...