title: Swift: Update UI - Entire function on main thread or just the UI update?
body: <p>I've read that the UI should always be updated on the main thread. However, I'm a little confused when it comes to the preferred method to implement these updates.</p>
  
  <p>I have various functions that perform some conditional checks then the result is used to determine how to update the UI. My question is should the entire function run on the main thread? Should just the UI update? Can / should I run the conditional checks on another thread? Does it depend on what the function does or how fast you want it done?</p>
  
  <p><strong>Example a function that changes the image inside an ImageView without threading:</strong></p>
  
  <pre><code>@IBAction func undoPressed(_ sender: Any) {
          if !previousDrawings.isEmpty {
              previousDrawings.remove(at: previousDrawings.count - 1)
              if let lastDrawing = previousDrawings.last {
                  topImageView.image = lastDrawing
              }
              else {
                  // empty
                  topImageView.image = nil
              }
          }
      }
  </code></pre>
  
  <p><strong>Should I be setting <code>topImageView.image</code> on the main thread? Like this:</strong></p>
  
  <pre><code> @IBAction func undoPressed(_ sender: Any) {
          if !previousDrawings.isEmpty {
              previousDrawings.remove(at: previousDrawings.count - 1)
              if let lastDrawing = previousDrawings.last {
                  DispatchQueue.main.async {
                      self.topImageView.image = lastDrawing
                  }
              }
              else {
                  DispatchQueue.main.async {
                      self.topImageView.image = nil
                  }
              }
          }
      }
  </code></pre>
  
  <p><strong>Should I be using a background thread for the conditional checks? Like this:</strong></p>
  
  <pre><code>@IBAction func undoPressed(_ sender: Any) {
          DispatchQueue.global(qos: .utility).async {
              if !previousDrawings.isEmpty {
                  previousDrawings.remove(at: previousDrawings.count - 1)
                  if let lastDrawing = previousDrawings.last {
                      DispatchQueue.main.async {
                          self.topImageView.image = lastDrawing
                      }
                  }
                  else {
                      DispatchQueue.main.async {
                          self.topImageView.image = nil
                      }
                  }
              }
          }
      }
  </code></pre>
  
  <p>If someone could explain what method is preferred and why that would be really helpful.</p>