14

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

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

4

3 回答 3

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 类的方法。唯一可能不是绝对必要的情况是在创建视图对象本身时,但所有其他操作都应在主线程上进行。

于 2013-02-24T07:52:08.363 回答
2

大多数 UIKit 对象,包括 的实例UIView只能从主线程/队列中操作。您不能将消息发送到UIView任何其他线程或队列上。这也意味着您不能在任何其他线程或队列上创建它们。

于 2013-02-24T06:21:13.427 回答
1

正如 rob 所说,UI 更改应该只在主线程上完成。您正在尝试从辅助线程添加。将您的代码[self.view addSubview:webView];更改为

[self.view performSelectorOnMainThread:@selector(addSubview:) withObject:webView waitUntilDone:YES];

于 2013-02-24T07:24:36.213 回答