我是Objective 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...
那么如何在主线程上添加子视图呢?
答案 0 :(得分:17)
因为您已经在使用调度队列。我不会使用performSelectorOnMainThread:withObject:waitUntilDone:
,而是在主队列上执行子视图添加。
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
文档:
线程注意事项
必须在主线程上对应用程序的用户界面进行操作。因此,您应该始终从应用程序主线程中运行的代码调用UIView类的方法。这可能不是绝对必要的唯一时间是创建视图对象本身,但所有其他操作应该在主线程上发生。
答案 1 :(得分:2)
大多数UIKit对象(包括UIView
的实例)必须从主线程/队列中操作 。您无法在任何其他线程或队列上向UIView
发送消息。这也意味着您无法在任何其他线程或队列上创建它们。
答案 2 :(得分:1)
正如rob所说,UI更改应仅在主线程上完成。您正在尝试从辅助线程添加。将代码[self.view addSubview:webView];
更改为
[self.view performSelectorOnMainThread:@selector(addSubview:) withObject:webView waitUntilDone:YES];