Question: I need to load 100 images in cells. If I use this method in tableView cellForRowAt: 

```
cell.cardImageView.image = UIImage(named: "\(indexPath.row + 1).jpg")

```

and start scrolling fast my `tableView` freezes. 

I use this method to load the image data in background that fix freezes:

```
func loadImageAsync(imageName: String, completion: @escaping (UIImage) -> ()) {
    DispatchQueue.global(qos: .userInteractive).async {
        guard let image = UIImage(named: imageName) else {return}
        DispatchQueue.main.async {
            completion(image)
        }
    }
}

```

in `tableView cellForRowAt` call this:

```
loadImageAsync(imageName: "\(indexPath.row + 1).jpg") { (image) in
        cell.cardImageView.image = image
}

```

But I have one bug may arise in this approach, such that while scrolling fast I may see old images for a while. How to fix this bug?

Answer: 
Your cells are being reused. 

When cell goes out of screen it gets to internal `UITableView`s reuse pool, and when you `dequeueReusableCell(withIdentifier:for:)` in `tableView(_:cellForRowAt:)` you get this cell again (see, "reusable" in name). It is important to understand `UITableViewCell`'s life cycle. `UITableView` does not hold 100 living `UITableViewCell`s for 100 rows, that would kill performance and leave apps without memory pretty soon.

**Why do you see old images in your cells?**
Again, cells are being reused, they keep their old state after reuse, you'll need to reset the image, they won't reset it by themselves. You can do that when you configure a new cell or detect when the cell is about to be reused. 

As simple as:

```
cell.cardImageView.image = nil // reset image
loadImageAsync(imageName: "\(indexPath.row + 1).jpg") { (image) in
        cell.cardImageView.image = image
}

```

The other way is detecting reuse and resetting. In your cell subclass:

```
override func prepareForReuse() {
    super.prepareForReuse()
    self.cardImageView.image = nil // reset
}

```

**Why do you see wrong images in your cells?** By the time `completion` closure sets image into `cardImageView`, `UITableViewCell` has been reused (maybe, even, more than once). To prevent this you could test if you're setting image in the same cell, for example, store image name with your cell, and then:

```
// naive approach

let imageName = "\(indexPath.row + 1).jpg"
cell.imageName = imageName
loadImageAsync(imageName: imageName) { (image) in
    guard cell.imageName == imageName else { return } 
    cell.cardImageView.image = image
}

```

There is a lot of stuff to take care of when designing lists, I won't be going into much detail here. I'd suggest to try the above approach and investigate the web on how to handle performance issues with lists.
in your cell class you need to declare 

```
override func prepareForReuse() {
    super.prepareForReuse()
}

```

to prepare the cell for the reuse