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

Luk*_*ger 28 xcode multithreading uikit ios swift

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

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

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

第二行发生此错误.

更新

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

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

Pun*_*rma 27

Xcode 9有一个新的运行时主线程检查器,它检测从后台线程调用UIKit并生成警告.

我知道它的意思是生成警告并且不会使应用程序崩溃,但您可以尝试为您的测试目标禁用主线程检查器.

在此输入图像描述

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

override func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.global().async {
        let v = UIView(frame: .zero)
    }
}
Run Code Online (Sandbox Code Playgroud)


Erh*_*rci 15

您可以使用此功能

func downloadImage(urlstr: String, imageView: UIImageView) {
    let url = URL(string: urlstr)!
    let task = URLSession.shared.dataTask(with: url) { data, _, _ in
        guard let data = data else { return }
        DispatchQueue.main.async { // Make sure you're on the main thread here
            imageview.image = UIImage(data: data)
        }
    }
    task.resume()
}
Run Code Online (Sandbox Code Playgroud)

如何使用这个功能?

downloadImage(urlstr: "imageUrl", imageView: self.myImageView)
Run Code Online (Sandbox Code Playgroud)


Adi*_*jan 7

主线程入口

您可以按如下方式输入主线程

      DispatchQueue.main.async { 
         // UIView usage
      }

Run Code Online (Sandbox Code Playgroud)

  • 点评来源:欢迎来到Stack Overflow!请不要只回答源代码。尝试提供有关您的解决方案如何工作的很好的描述。请参阅:[我如何写一个好的答案?](https://stackoverflow.com/help/how-to-answer)。谢谢 (3认同)