如何确定是否需要在DispatchQueue.main.async中放置语句?

时间:2019-01-21 02:18:02

标签: ios swift uikit

我试图在viewDidLoad:(canvas.bounds)中获得子视图的绑定大小

最初,我没有使用DispatchQueue.main.async包装器,并且大小没有正确返回。因此,通过实验,我将该语句包装在主线程队列中。然后它起作用了。

我知道有一条准则说“与UI相关的操作需要放在主线程中”。但这如何转化为实际的经验法则:

  1. 如果我只是查询UI属性,例如获取边界大小,我是否 需要将其包装在主线程队列中?
  2. 如果我要更改UI 财产,例如更改边界大小,我需要将其包装在里面吗 主线程队列? (我猜可能是)

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    
    // stack views
    view.addSubview(photoView)
    view.addSubview(canvas)
    
    DispatchQueue.main.async {
        self.canvas.startPoint = CGPoint.zero
        self.canvas.endPoint = CGPoint(x: self.canvas.bounds.width / 2.0, y: self.canvas.bounds.height)
    
        self.canvas.setNeedsDisplay()
    }
    

实际上,这引出了我想自然地问到的另一个问题:必须将代码包装在调度主程序中看起来“不干净”。如果您必须包装它,这是否意味着'viewDidLoad'不是要使用的正确生命周期?应该有一个更合适的生命周期,而不需要调度主包装?

1 个答案:

答案 0 :(得分:4)

您的问题是viewDidLoad不是获取任何大小文件的正确位置。还为时过早。

使用DispatchQueue.main.async只是将代码延迟到刚好已更新大小(可能是)。

正确的解决方案是将尺寸放置在正确的位置。使用viewDidAppearviewDidLayoutSubviews