Pinit 셀 재사용 이슈

728x90

발생했던 문제

Pinit 에서는 이미지가 있을때는 그대로 보여주고, 이미지가 없다면 기록한 위치의 지도를 스냅샷으로 보여준다.

여기서 문제가 발생했다.

이미지는 저장된걸 바로 보여주지만, 스냅샷은 주소만 보내주고 셀에서 스냅샷 이미지를 로드하기에 몇 초 더 지연시간이 생긴다.

이때 셀이 엄청 많을때 스크롤을 하면, 재사용 때문에 이전에 사용된 이미지 또는 스냅샷이 먼저 보이고 나중에 제대로 된 스냅샷으로 갈아끼워지는 문제가 있었다.

문제점 파악

문제점은 역시 셀 재사용 매커니즘을 제대로 이해못하고 지연시간을 고려하지 않았기 때문이다.

셀이 재사용 될 때 이전 데이터를 그대로 들고 있다는 것 역시 인지하지 못했기 때문에 일어난 문제였다.

셀이 화면에서 사라지면 셀 자체가 지워지지 않고 이전 데이터 그대로 Reusable Queue에 할당된다. (해제되지 않음)

문제 해결

셀 코드

func configure(model: PinEntity) {
    pinDateLabel.text = model.date.formatted()
    pinTitleLabel.text = model.title

    if let image = model.mediaPath {
        thumbnailImageView.image = image
    }
    else {
        captureMapSnapshotWithPin(
            center: CLLocationCoordinate2D(
                latitude: model.latitude,
                longitude: model.longitude
            ),
            imageSize: CGSize(
                width: contentView.frame.height,
                height: contentView.frame.width
            )) { image in
                self.thumbnailImageView.image = image ?? UIImage(systemName: "house")
            }
    }

    setupLayout()
}

이 부분에서 else로 들어가면 딜레이가 생기는 것, 썸네일이 제대로 뜨기 전 까진 기본 이미지가 뜨게 만들어뒀다.

앞에서 봤던것처럼 셀 자체의 데이터가 지워진채로 재사용 되는것이 아니기 때문에, 설정시 데이터를 다시 초기화해주면 쉽게 해결이 가능했다.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? PinRecordCell
    else { return UICollectionViewCell() }

    cell.thumbnailImageView.image = nil
    cell.configure(model: data[indexPath.row])
    cell.layoutIfNeeded()

    return cell
}

cell.configure 내에서 초기화해주는게 좋겠지만, 급하게 제출하느라 cellForItemAt 에서 데이터를 지워줬다.


728x90