xcode 在后台线程上创建一个视图,将其添加到主线程上的主视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15049224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 02:50:37  来源:igfitidea点击:

creating a view on a background thread, adding it the main view on the main thread

iosobjective-cxcode

提问by Huang

I am new to objective C, coming from .NET and java background.

我是目标 C 的新手,来自 .NET 和 java 背景。

So I need to create some UIwebviews asynchronously, I am doing this on my own queue using

所以我需要异步创建一些 UIwebviews,我在我自己的队列中使用

     dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL);
     dispatch_async(queue, ^{
        // create UIwebview, other things too
             [self.view addSubview:webView];
        });

as you owuld imagine this throws an error :

正如您所想象的那样,这会引发错误:

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

So how can I add the subview on the main thread?

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

回答by Florian

Since you are already using dispatch queues. I wouldn't use performSelectorOnMainThread:withObject:waitUntilDone:, but rather perform the subview addition on the main queue.

由于您已经在使用调度队列。我不会使用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];
    });
});

It is fine to instantiate the UIWebViewon a background queue. But to add it as a subview you must be on the main thread/queue. From the UIViewdocumentation:

可以UIWebView在后台队列中实例化。但是要将其添加为子视图,您必须在主线程/队列上。从UIView文档:

Threading Considerations

线程注意事项

Manipulations to your application's user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.

对应用程序用户界面的操作必须发生在主线程上。因此,您应该始终从应用程序主线程中运行的代码调用 UIView 类的方法。这可能不是绝对必要的唯一时间是在创建视图对象本身时,但所有其他操作都应该在主线程上进行。

回答by rob mayoff

Most UIKit objects, including instances of UIView, must be manipulated onlyfrom the main thread/queue. You cannot send messages to a UIViewon any other thread or queue. This also means you cannot create them on any other thread or queue.

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

回答by kaar3k

As rob said the UI changes should be done only on main thread.You are trying to add from a secondary thread.Change your code [self.view addSubview:webView];to

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

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

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