UITableView
アプリの初期読み込み中に複数の API リクエストを送信します。API リクエストが返されるたびに、新しい行を に追加しますUITableView
。したがって、最初の読み込みでは、行がランダムな順序でランダムな時間に追加されます (ほとんどの場合、すべてが 1 秒以内に発生します)。
セルのセットアップ中に、Async メソッドを呼び出してMKMapKit
MKMapSnapshotter
画像を生成します。
以前は問題なく非同期の画像読み込みを使用していましたが、画像が間違ったセルに表示されることはめったになく、その理由がわかりません。
に切り替えてみましたDiffableDataSource
が、問題は残ります。
私DiffableDataSource
の場合、画像の非同期が返されたときに呼び出されるセルにクロージャーを渡し、変更された場合に現在のセルをフェッチします。
let dataSource = DiffableDataSource(tableView: tableView) {
(tableView, indexPath, journey) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "busCell", for: indexPath) as! JourneyTableViewCell
cell.setupCell(for: journey) { [weak self] () -> (cell: JourneyTableViewCell?, journey: Journey?) in
if let self = self
{
let cell = tableView.cellForRow(at: indexPath) as? JourneyTableViewCell
let journey = self.sortedJourneys()[safe: indexPath.section]
return (cell, journey)
}
return(nil, nil)
}
return cell
}
これが私のセルセットアップコードです:
override func prepareForReuse() {
super.prepareForReuse()
setMapImage(nil)
journey = nil
asyncCellBlock = nil
}
func setupCell(for journey:Journey, asyncUpdateOriginalCell:@escaping JourneyOriginalCellBlock) {
self.journey = journey
// Store the async block for later
asyncCellBlock = asyncUpdateOriginalCell
// Map
if let location = journey.location,
(CLLocationCoordinate2DIsValid(location.coordinate2D))
{
// Use the temp cached image for now while we get a new image
if let cachedImage = journey.cachedMap.image
{
setMapImage(cachedImage)
}
// Request an updated map image
journey.createMapImage {
[weak self] (image) in
DispatchQueue.main.async {
if let asyncCellBlock = self?.asyncCellBlock
{
let asyncResult = asyncCellBlock()
if let cell = asyncResult.cell,
let journey = asyncResult.journey
{
if (cell == self && journey.id == self?.journey?.id)
{
self?.setMapImage(image)
// Force the cell to redraw itself.
self?.setNeedsLayout()
}
}
}
}
}
}
else
{
setMapImage(nil)
}
}
UITableView
これが短期間に数回更新されるだけの競合状態であるかどうかはわかりません。