1

In a global, async closure, I'd like to initialise a UIView on the main thread. I thought this code would possibly do it, but I get an Analyser warning:

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

let view: UIView = { // Line with the warning
      DispatchQueue.main.sync {
          return UIView()
      }
}()
Mannopson
  • 2,634
  • 1
  • 16
  • 32
Josh Paradroid
  • 1,172
  • 18
  • 45

2 Answers2

3

I'll be helpful if u post more of the code so we could understand the context better. Anyway, this should work nicely:

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

I hope that helps.

DanielH
  • 685
  • 5
  • 6
  • 1
    Using a completion handler would be cleaner. Technically, I would recommend split it into two functions anyway. – Sulthan Oct 30 '17 at 15:14
  • @Sulthan, I agree. My code wasn't by 'best practice' standards but it should be executed as expected. – DanielH Oct 30 '17 at 15:17
0

Try something like that:

You can keep using your own implementation, without DispatchQueue.main.sync

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

However you can go back to the main thread anytime:

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

Use the .async, it's gives you an independent thread

Mannopson
  • 2,634
  • 1
  • 16
  • 32