【问题标题】:Initialising UIView in main thread from a background thread从后台线程在主线程中初始化 UIView
【发布时间】:2017-10-30 14:11:20
【问题描述】:

在一个全局的异步闭包中,我想在主线程上初始化一个UIView。我认为这段代码可能会这样做,但我收到了分析器警告:

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

let view: UIView = { // Line with the warning
      DispatchQueue.main.sync {
          return UIView()
      }
}()

【问题讨论】:

  • 这样做的目的是什么?你能说说你的总体目标是什么吗?
  • 我正在从一些 xib 生成 PDF。我需要一个容器给他们。这是唯一给出警告的行。
  • 我觉得这很奇怪!你试过没有DispatchQueue.main.sync吗?为什么需要这个?
  • @JoshParadroid 你是对的!诚实地。这不是我。祝你好运!
  • @Mannopson 抱歉——我不是故意要指责的!

标签: swift multithreading grand-central-dispatch dispatch-async background-thread


【解决方案1】:

如果您发布更多代码,我会很有帮助,以便我们更好地理解上下文。 无论如何,这应该很好用:

class SomeViewController: UIViewController {

    private var customView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupCustomView()
    }

    private func setupCustomView() {
        DispatchQueue.global().async {
            /*
             1. Do some preperation / data init' on background thread.
             2. When ready, perform UI dependent initialization on main thread.
             */
            DispatchQueue.main.async {

                /* Initialize `customView` on the main queue. for example: */
                self.customView = UIView()
                self.view.addSubview(self.customView)
                self.customView.backgroundColor = .red
                self.customView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
            }
        }
    }
}

希望对你有帮助。

【讨论】:

  • 使用完成处理程序会更干净。从技术上讲,我还是建议将它分成两个函数。
  • @Sulthan,我同意。我的代码不符合“最佳实践”标准,但应该按预期执行。
【解决方案2】:

试试这样的:

您可以继续使用自己的实现,无需DispatchQueue.main.sync

let view: UIView = { 
      return UIView()
}()

不过你可以随时回到主线程:

DispatchQueue.main.async {
  self.view.addSubview(view) 
}

使用.async,它给你一个独立的线程

【讨论】:

    猜你喜欢
    • 2017-07-30
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多