title: TableViewCells Array reorders itself after updating TableView
body: <p><strong>hello my fellow programmer friends,</strong></p>
  
  <p>i have run into a problem with swift's UITableView and I just can't find the error. </p>
  
  <p>I am pretty expirienced with iOS's TableViews and I know how they use a queue to be as performantly as possible.</p>
  
  <p>I usually just build an array of UITableViewCells in my ViewController and update the TableView based on that array. With this technique, I can use one DataSource Class for all my TableViews, which is very clean and always worked fine.</p>
  
  <p>Until now: 
  This is my first TableView with many cells of the same type, which I add new cells to if the user presses on the last cell, a "LoadMore" cell.
  But the problem is, if said "LoadMore" cell gets pressed, as soon as the TableView gets updated, the TableView and even the tableViewCells array reorder themselves, and even contain double entries which cannot be presented correctly.</p>
  
  <p>I can't find the reason for this. Everything is normal, and all the data and the tableViewCells array definitely are correct, until TableViews reloadData() gets called. I checked many times now what they contain before and after the update.</p>
  
  <p>Here is the (reduced) code for my ViewController, which by the way only contains the TableView:</p>
  
  <pre><code>import UIKit
  
  class UserDataTableViewController: UIViewController, UITableViewDelegate {
  
      @IBOutlet weak var tableView: UITableView!
  
      //Auto updating TableView
      var tableViewCells = [UITableViewCell]() {
          didSet {
              dataSource.update(with: tableViewCells)
              tableView.reloadData()
              tableView.beginUpdates()
              tableView.endUpdates()
          }
      }
  
      //DataSource for Table View
      var dataSource = NormalTableDataSource(cells: nil)
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          //TableView
          tableView.dataSource = dataSource
          tableView.delegate = self
          tableView.separatorColor = .darkText
  
          //get next data
          nextData()
      }
  
      func nextData() {
          if let data = self.data {
              //some code that finds the next data and then calls:
              addDataToTableView(data: nextData, morePages: true)
          }
      }
  
      func addDataToTableView(data: Array&lt;Any&gt;, morePages: Bool = false) {
          //create temp array out of old tableViewCells array
          var tempCells = tableViewCells
  
          //remove LoadMore cell if it exists
          if (tempCells.count &gt; 0) {
              tempCells.removeLast()
          }
  
          //(Rating is a simple Struct)
          if let ratings = data as? [Rating] {
              //This loop runs aprox. 25 times
              for rating in ratings {
                  let cell = tableView.dequeueReusableCell(withIdentifier: "UserRatedAlbumCell") as! UserRatedAlbumCell
                  cell.update(rating: rating)
                  tempCells.append(cell)
              }
          }
  
          //add LoadMore cell
          if (morePages) {
              let loadMoreCell = tableView.dequeueReusableCell(withIdentifier: "LoadMoreCell")!
              tempCells.append(loadMoreCell)
          }
  
          //update array, which automatically updates the tableView
          self.tableViewCells = tempCells
      }
  
      func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -&gt; CGFloat {
          return tableViewCells[indexPath.row].frame.size.height
      }
  
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          let cell = tableViewCells[indexPath.row]
  
          if (cell.reuseIdentifier == "LoadMoreCell") {
              self.nextData()
          }
  
          tableView.deselectRow(at: indexPath, animated: true)
      }
  }
  </code></pre>
  
  <p>And here is the (also a little reduced) code inside the "UserRatedAlbumCell" class:</p>
  
  <pre><code>import UIKit
  
  class UserRatedAlbumCell: UITableViewCell {
  
      @IBOutlet weak var albumCoverImage: UIImageView!
      @IBOutlet weak var albumNameLabel: UILabel!
  
      //data
      var album: Album?
      var rating: Rating?
  
      func update(rating: Rating) {
          self.rating = rating
          albumNameLabel.text = ""
          albumCoverImage.image = nil
  
          //---Some async task with completion block that returns "album":
          {
              if let album = album {
                  DispatchQueue.main.async {
                      self.update(album: album, rating: rating)
                  }
              }
          }
          //---
      }
  
      func update(album: Album) {
          self.album = album
  
          albumNameLabel.text = album.attributes?.name
  
          if let url = album.attributes?.artwork.url(forWidth: 150) {
              albumCoverImage.downloaded(with: url)
          }
      }
  }
  </code></pre>
  
  <p>And here is my "NormalTableDataSource", which is, as previously said, used in nearly all of my TableViews:</p>
  
  <pre><code>import UIKit
  
  class NormalTableDataSource: NSObject, UITableViewDataSource {
  
      private var cells: [UITableViewCell]?
  
      init(cells: [UITableViewCell]?) {
          self.cells = cells
      }
  
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
          return cells?.count ?? 0
      }
  
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
  
          if let cells = cells {
              return cells[indexPath.row]
          } else {
              return UITableViewCell()
          }
      }
  
      func update(with cells: [UITableViewCell]?) {
          self.cells = cells
      }
  }
  </code></pre>
  
  <p>Does anyone have any idea why this might be? 
  If requested, I can provide screenshots of what happens with the TableView. But I can tell you that, as soon as LoadMore gets pressed the first time, all cells reorder themselves and there are many blank cells, probably caused by double entry's in the tableViewCells array.</p>
  
  <p>Thanks for any help!</p>