【问题标题】:Xcode UIView.init(frame:) must be used from main thread onlyXcode UIView.init(frame:) 只能在主线程中使用
【发布时间】:2018-03-03 21:51:17
【问题描述】:

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

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

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

这个错误出现在第二行。

更新

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

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

【问题讨论】:

  • 我知道这个新规则,但我想知道您仍然可以将多少工作卸载到后台线程...

标签: ios swift xcode multithreading uikit


【解决方案1】:

对于目标 C:

 dispatch_async(dispatch_get_main_queue(), ^{

        // UIView usage
        self.view.userInteractionEnabled = YES;
    });

【讨论】:

    【解决方案2】:

    主线程入口

    可以如下进入主线程

    DispatchQueue.main.async { 
        // UIView usage
    }
    

    【讨论】:

    • 点评来源: 欢迎来到 Stack Overflow!请不要只用源代码回答。尝试对您的解决方案如何工作提供一个很好的描述。见:How do I write a good answer?。谢谢
    【解决方案3】:

    Xcode 9 有一个新的运行时 Main Thread Checker,它检测从后台线程对 UIKit 的调用并生成警告。

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

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

    override func viewDidLoad() {
        super.viewDidLoad()
    
        DispatchQueue.global().async {
            let v = UIView(frame: .zero)
        }
    }
    

    【讨论】:

    • 现在做到了。谢谢!
    • 在我的例子中,我从 URLSession 请求中调用了一个方法。
    【解决方案4】:

    你可以使用这个功能

    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()
    }
    

    这个功能怎么用?

    downloadImage(urlstr: "imageUrl", imageView: self.myImageView)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-31
      • 2019-04-29
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多