Xcode UIView.init(frame:) 只能在主线程中使用 [英] Xcode UIView.init(frame:) must be used from main thread only

查看:28
本文介绍了Xcode UIView.init(frame:) 只能在主线程中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在后台线程中呈现一些视图,以免影响主线程.在 Xcode 9 之前,这从来都不是问题.

DispatchQueue.global(qos: .background).async {让 customView = UIView(frame: .zero)DispatchQueue.main.async {self.view.addSubview(customView)}}

<块引用>

UIView.init(frame:) 只能在主线程中使用

这个错误出现在第二行.

更新

Apple UIView 文档实际上在 Threading Considerations 部分中说:

<块引用>

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

解决方案

Xcode 9 有了新的运行时

我在一个示例项目中尝试了此代码,调试器在该问题处暂停(正如它应该的那样),但应用程序没有崩溃.

覆盖 func viewDidLoad() {super.viewDidLoad()DispatchQueue.global().async {让 v = UIView(frame: .zero)}}

I'm trying to render some views in background thread to not affect the main thread. That was never a problem before Xcode 9.

DispatchQueue.global(qos: .background).async {
    let customView = UIView(frame: .zero)
    DispatchQueue.main.async {
        self.view.addSubview(customView)
    }
}

UIView.init(frame:) must be used from main thread only

This error occurs in the second line.

Update

The Apple UIView Documentation actually says in the Threading Considerations section:

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.

解决方案

Xcode 9 has a new runtime Main Thread Checker that detects call to UIKit from a background thread and generate warnings.

I know its meant to generate warnings and not crash the app, but you can try disabling Main Thread Checker for your test target.

I tried this code in a sample project, the debugger paused at the issue (as it is supposed to), but the app didn't crash.

override func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.global().async {
        let v = UIView(frame: .zero)
    }
}

这篇关于Xcode UIView.init(frame:) 只能在主线程中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆