title: Download and cache images in UITableViewCell
body: <p><em>Note: Please no libraries. This is important for me to learn. Also, there are a variety of answers on this but none that I found solves the issue nicely. Please don't mark as duplicate. Thanks in advance!</em></p>
  
  <p>The problem I have is that if you scroll really fast in the table, you will see old images and flickering. </p>
  
  <ul>
  <li>The solution from the questions I read is to cancel the <code>URLSession</code>
  data request. But I do not know how to do that at the correct place
  and time. There might be other solutions but not sure.</li>
  </ul>
  
  <p>This is what I have so far:</p>
  
  <p><strong>Image cache class</strong></p>
  
  <pre><code>class Cache {
  
      static let shared = Cache()
  
      private let cache = NSCache&lt;NSString, UIImage&gt;()
      var task = URLSessionDataTask()
      var session = URLSession.shared
  
      func imageFor(url: URL, completionHandler: @escaping (image: Image? error: Error?) -&gt; Void) {
              if let imageInCache = self.cache.object(forKey: url.absoluteString as NSString)  {
                  completionHandler(image: imageInCache, error: nil)
                  return
              }
  
              self.task = self.session.dataTask(with: url) { data, response, error in
  
                  if let error = error {
                      completionHandler(image: nil, error: Error)
                      return
                  }
  
                  let image = UIImage(data: data!)
  
                      self.cache.setObject(image, forKey: url.absoluteString as NSString)
                      completionHandler(image: image, error: nil)
                  }
  
              self.task.resume()
      }
  }
  </code></pre>
  
  <p><strong>Usage</strong></p>
  
  <pre><code>func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
      let myImage = images[indexPath.row]
  
      if let imageURL = URL(string: myImage.urlString) {
          photoImageView.setImage(from: imageURL)
      }
      return cell
  }
  </code></pre>
  
  <p>Any thoughts?</p>