title: tableView.reloadData() does not refresh table until scrolled, even with dispatch_async
body: <p>I'm having a rather common issue, but the solutions so far have not given me the desired result.</p>
  
  <p>I have a <code>UITableView</code> that I am populating with information that I have parsed from a JSON pulled from the web at run time. The JSON retrieval starts in <code>func viewDidLoad()</code> using the <code>NSURLSession.dataTaskWithURL(NSURL, completionHandler)</code> function. The cells of the table are then populated within the <code>completionHandler</code>.</p>
  
  <p>The cells used in the table are custom, and all UI elements in the cell have default values set through the interface builder.</p>
  
  <p>When the table appears it is completely empty, though it does have the proper cell height. The reason I found for this behavior is that the <code>reloadData</code> function isn't being called at the right time due to multithreading/multiprocessing and the suggested solution is to have</p>
  
  <pre><code>dispatch_async(dispatch_get_main_queue(), {
      self.tableView.reloadData()
  })
  </code></pre>
  
  <p>somewhere in the code to allow the reload to occur correctly. However, this only partially works. The table flickers with what looks like content, and then immediately goes blank again until I scroll. Once I scroll the <code>reloadData</code> function works as expected, but only after I scroll.</p>
  
  <p>I've tried having the <code>reloadData</code> function in various locations (such as in <code>viewWillAppear</code>) with no luck. Are there any ideas or troubleshooting tips that I can try?</p>
  
  <p><strong>Edit #1 - Request for completion handler</strong></p>
  
  <pre><code>var listTask = session.dataTaskWithURL(listUrl, completionHandler: {(data, response, error) in
      if error == nil {
          var json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil) as NSDictionary
          var topGames = json["top"] as [NSDictionary]
          var currGame:NSDictionary
          var toAdd:Game
          for var i=0; i &lt; topGames.count; ++i {
              currGame = topGames[i]["game"] as NSDictionary
              toAdd = Game(
                  id: String(currGame["_id"] as CLong),
                  name: currGame["name"] as NSString,
                  boxArtImageUrl: (currGame["box"] as NSDictionary)["medium"] as NSString,
                  boxArtImage: nil,
                  isFetchingBoxArt: false,
                  totalViewers: topGames[i]["viewers"] as Int,
                  totalChannels: topGames[i]["channels"] as Int,
                  topChannel: "N/A")
              self.games.append(toAdd)
          }
          dispatch_async(dispatch_get_main_queue(), {
              self.tableView.reloadData()
          })
      }
  }
  </code></pre>
  
  <p>Note that the self.games array is used in <code>func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCel</code> to fill in the information in the cells.</p>
  
  <p><strong>Edit #2 - Request for <code>cellForRowAtIndexPath</code></strong></p>
  
  <pre><code>func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
      var cell:TopGameListCell = self.tableView.dequeueReusableCellWithIdentifier("topGameCell") as TopGameListCell
      if games.count &gt; 0 {
          var game:Game = games[indexPath.row]
          cell.nameLabel?.text = game.name
          cell.totalViewersLabel.text = String(game.totalViewers)
          cell.totalChannelsLabel.text = String(game.totalChannels)
          cell.topChannelLabel.text = game.topChannel
          if game.boxArtImage != nil {
              cell.boxArtImageView.image = game.boxArtImage
          } else {
              if(!game.isFetchingBoxArt) {
                  cell.boxArtImageView.image = placeholderImage
                  gatherGameBoxArtImageForCell(game.boxArtImageUrl, indexPath: indexPath)
              }
          }
      }
      return cell;
  }
  </code></pre>
  
  <p>I forgot about the extra fetch that I start within the <code>gatherGameBoxArtImageForCell</code>. Basically if I don't already have the image, download it. The if/else for the image seems to be causing the flicker to occur. If I let it sit long enough, it finally shows the table. The idea for me is that the placeholder image would show until the image is downloaded, and then <code>reloadData</code> is called after the image is downloaded. Here is the image fetch <code>completionHandler</code>:</p>
  
  <pre><code>var task = session.dataTaskWithURL(url, completionHandler: {(data, response, error) in
      var game = self.games[indexPath.row]
      if error == nil {
          if(game.boxArtImage == nil) {
              var cellForImage:TopGameListCell? = self.tableView.cellForRowAtIndexPath(indexPath) as? TopGameListCell
              if cellForImage != nil {
                  self.games[indexPath.row].boxArtImage = UIImage(data: data)
                  cellForImage?.boxArtImageView.image = self.games[indexPath.row].boxArtImage
              }
          }
      } else {
          println(error)
      }
      game.isFetchingBoxArt = false
      self.tableView.reloadData()
  })
  </code></pre>