Если я правильно понял, вы передаете в ячейку ссылку на изображение, и дальше асинхронно загружаете изображение с этого адреса.
В этом случае проблема состоит в том, что получение изображение - процесс не быстрый, и если проскроллить ячейку достаточно быстро, тогда все поломается.
Например, мы увидели ячейку №1, сработал метод загрузки изображения, пошел запрос на адрес, в этом время ячейка ушла из области, и мы увидели другую, она тоже посылает запрос на сервер, но в этом время у нас приходит ответ с первого запроса, и ячейка №2 уже получит по своему запросу, но данные будут от первого запроса, и соответственно подставится неправильное изображение.
Чтобы этого избежать, нам нужно в момент, когда ячейка пропадет из области видимости, останавливать запрос, чтобы мы не получили ненужный нам ответ.
Я предлагаю следующее решение:
Ставим наблюдателя, при получении строки с адресом изображения будет проверять, можно ли сформировать ссылку из указанного адреса, если не получится - тогда поставит дефолтное изображение
var imageURLString: String? {
didSet {
DispatchQueue.global(qos: .utility).async { [unowned self] in
guard imageURLString != "",
let imageURLString = self.imageURLString,
let imageURL = URL(string: imageURLString) else {
DispatchQueue.main.async {
self.ImageView.image = UIImage(named: "default")
}
return
}
loadImage(imageURL: imageURL)
}
}
}
Если ссылка получена, вызывается этот метод, который получит данные и подставит в изображение, либо поставит дефолтную картинку, если данные не пришли по тем или иным причинам
fileprivate func loadImage(imageURL: URL) {
dataTask = URLSession.shared.dataTask(with: imageURL, completionHandler: { data, response, error in
if let data = data,
let image = UIImage(data: data) {
DispatchQueue.main.async { [unowned self] in
self.ImageView.image = image
}
} else {
DispatchQueue.main.async { [unowned self] in
self.ImageView.image = UIImage(named: "default")
}
}
})
dataTask?.resume()
}
Самое главное. Метод остановит загрузку если ячейка была удалена из области видимости.
override func prepareForReuse() {
super.prepareForReuse()
dataTask?.cancel()
ImageView.image = UIImage(named: "default")
}
Код выше - прописан в классе ячейки коллекции.