在后台线程上创建一个视图,在主线程上添加主视图

时间:2013-02-24 06:18:45

标签: ios objective-c xcode

我是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...

那么如何在主线程上添加子视图呢?

3 个答案:

答案 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];