Создавая представление на фоновом потоке, добавляя его основной вид в основной поток
Я новичок в объекте C, исходя из .NET и java фона.
Поэтому мне нужно создать некоторые UIwebviews асинхронно, я делаю это в своей собственной очереди, используя
dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL);
dispatch_async(queue, ^{
// create UIwebview, other things too
[self.view addSubview:webView];
});
как вы думаете, это порождает ошибку:
bool _WebTryThreadLock(bool), 0xa1b8d70: 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...
Итак, как я могу добавить subview в основной поток?
Ответы
Ответ 1
Поскольку вы уже используете очереди отправки. Я бы не использовал performSelectorOnMainThread:withObject:waitUntilDone:
, а скорее выполнил добавление subview в основной очереди.
dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL);
dispatch_async(queue, ^{
// create UIwebview, other things too
// Perform on main thread/queue
dispatch_async(dispatch_get_main_queue(), ^{
[self.view addSubview:webView];
});
});
Прекрасно создавать экземпляр UIWebView
в фоновом режиме. Но чтобы добавить его в качестве подзаголовка, вы должны быть в основном потоке/очереди. Из документации UIView
:
Вопросы Threading
Манипуляции к вашим приложениям пользовательский интерфейс должен присутствовать в основном потоке. Таким образом, вы всегда должны вызывать методы класса UIView из кода, запущенного в основном потоке вашего приложения. Единственный раз, когда это может быть не обязательно, необходимо создать объект представления, но все другие манипуляции должны произойти в основном потоке.
Ответ 2
Большинство объектов UIKit, включая экземпляры UIView
, должны обрабатываться только из основного потока/очереди. Вы не можете отправлять сообщения в UIView
в любом другом потоке или очереди. Это также означает, что вы не можете создавать их в любом другом потоке или очереди.
Ответ 3
Как сказал rob, изменения пользовательского интерфейса должны выполняться только на основном потоке. Вы пытаетесь добавить из вторичного потока. Измените свой код [self.view addSubview:webView];
на
[self.view performSelectorOnMainThread:@selector(addSubview:) withObject:webView waitUntilDone:YES];