Cell의 재사용성에 대해 (with prepareForReuse())

Jason·2023년 7월 7일
0
post-thumbnail

총 3개의 섹션(Section)을 가지는 collectionView를 구현해보았고
생각보다 자주 놓치는 부분이 있어서 해당 내용을 정리해보았습니다.

🤯 문제 발생

collectionView의 DataSource를 생성하는 과정에서 필수 메서드인

func collectionView( ... , cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

위 내용을 구현하다보면 자연스럽게 아래와 같이 dequeue 코드를 작성하게됩니다.

guard let cell = collectionView.dequeueReusableCell(
	withReuseIdentifier: 'Cell'.identifier, for: indexPath) as? 'CustomCell' else { 
    return UICollectionViewCell()
}

말그대로 dequeue(대기열에서 빼냄)에서 UICollectionViewCell을 재사용한다는 뜻이 내포되어있기에 초기화까지 이루어진다고
생각할 수 있지만 직접 실행해보면 잔여물? 초기화되지 않고 남으면서 셀의 재사용성에 대해 문제가 발생합니다.
아래의 예시를 보면 가격 및 뱃지가 보여지는 UI에 이전에 없었던 가격과 뱃지가 나타나는 현상을 볼 수 있겠습니다.

🙌🏻 해결과정

🅰️ prepareForReuse() 메서드에 대하여

View를 다시 사용할 수 있도록 준비하는 데 필요한 초기화(clean-up)를(을) 수행합니다.

요약 내용으로만 보아도 View를 초기화하는 역할을 수행하는 메서드이며
좀 더 자세한 내용을 정리해보면 아래와 같습니다.

  1. 그냥 호출해서 사용하면 아무런 동작이 없음으로 해당 메서드를 재정의하여 사용합니다.
  2. CollectionView가 view의 사용을 위해 큐에서 빼는 경우,
    해당 dequeue 메서드가 View를 코드로 반환하기 전prepareForReuse() 메서드를 호출합니다.
  3. 이 방법을 사용하여 View에 새 데이터를 할당하지 않습니다. 이는 DataSource의 책임입니다.

🌐 공식문서: prepareForReuse() | Apple Developer Documentation - UICollectionReusableView

🅱️ 메서드를 사용하여 해결하기

메서드의 원형은 아래와 같습니다.

override func prepareForReuse() {
    super.prepareForReuse()

    // 셀을 속성을 초기화 해주는 코드. 
    // (값을 할당하는 코드는 데이터소스에 작성합니다.)
}

재사용 되는 cell을 dequeue 할 때 이전에 사용 되었던 흔적이 남던 내용을 prepareForReuse를 통해 해결해보도록 하겠습니다.

private func prepareForReuse(stackView: UIStackView) { 
	stackView.subviews.forEach { view in 
    	view.removeFromSuperview() 
	}
}
    
override func prepareForReuse() {
	super.prepareForReuse()
    foodImageView.image = nil
	prepareForReuse(stackView: foodInformationStackView.foodPriceStackView)
	prepareForReuse(stackView: foodInformationStackView.badgeStackView)
}

위와 같이 작성하여 시뮬레이션을 확인해보았더니 아래와 같이 잘 해결됨을 볼 수 있었습니다.

💡 학습하며 알게된 점

  1. TableView와 CollectionView 2가지의 view에서 따로 메서드가 존재한다.
    그래도 동작 원리는 비슷하다.
  2. prepareForReuse()메서드가 호출된 다음 DataSource의 cellForRowAt 메서드가 호출되는 순서를 알게되었다.
  3. dequeue 메서드만으로 초기화하는데는 부족한 점이 있으며 Cell의 속성을 초기화하는 부분으로 사용하도록한다.

🌐 참고 사이트

iOS) prepareForReuse() 사용해서 셀을 초기화해보자
[iOS] prepareForReuse란?
StackOverflow | What is the correct way to use prepareForReuse?
prepareForReuse() | Apple Developer Documentation - UITableViewCell

profile
🧑🏼‍💻 iOS developer

0개의 댓글