iOS/개념

[iOS] TableView와 CollectionView의 reusable Cell

누알라리 2021. 12. 29. 00:50

노션링크: https://acoustic-string-66e.notion.site/tableview-collctionview-cell-34dc8e520c594a7b9bc3860a873b1ea5

개요

UITableView, UICollectionView의 기본 사용방법은 다음과 같습니다.

  1. cell class를 tableView init단계에서 register 해준다.
  2. delegate에서 등록한 cell 클래스를 reusable로 만들어서 사용한다.

cell 재사용에 관한 개념을 너무 대충 알고 사용하고있다는 생각이 들어 이 기회에 공부해보겠습니다.

https://developer.apple.com/documentation/uikit/uitableview/1614878-dequeuereusablecell

해당 문서를 참고했습니다.


개요에 쓴 사용방법을 코드로 쓰면 다음과 같습니다.

  1. tableView 구성 시 사용할 cell class와 identifier을 register 해준다.
let tableView = UITableView(frame: .zero, style: .grouped)
tablieView.then { [unowned self] in
	$0.datasource = self
	$0.register(CustomCell.self, forCellReuseIdentifier: "CustomCellIdentifier")
}
  1. UITableViewDataSource의 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 에 등록한 cell을 reusableCell로 구성해준다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCellIdentifier", for: indexPath) as! CustomCell
        return cell
}

오늘의 핵심은 dequeueReusableCell(withIdentifier:for:) 메서드 입니다.

메서드명을 직역하자면 reusableCell을 queue에서 뺀다. 로 해석할 수 있겠네요.

 

아마 내부적으로는 register된 cell class들로 한 화면에 보이거나 보이는 갯수에 한 두개 추가한 cell 갯수를 reusable Queue에 추가해놓은 뒤 reusable될 때 Identifier로 cell을 찾아 dequeue해서 화면을 구성하는듯 합니다.

 

공식문서를 볼까요?

dequeueReusableCell 함수는 datasource delegate의 tableView(_: cellForRowAt:) 함수에서만 불려야 합니다.

 

이 함수는

  1. specified된(= tableView에 미리 register 된 cell 클래스를 의미하는 듯) 타입의 이미 존재하는 cell을 리턴하거나
  2. register된 cell class로 새로 생성한 cell을 리턴합니다.

이 함수는 오직 tableView(_: cellForRowAt:) 함수에서만 불려야 합니다.

(있을까 싶지만) 다른곳에서 cell을 생성하고 싶다면 dequeueReusableCell(withIdentifier:) 함수를 불러야합니다.

 

register된 class로 부터 cell을 생성할 때는 init(style: reuseIdntifier:) 함수를 불러 cell을 생성하고 초기화 합니다.

이미 존재하는 cell이 reuse될 경우 cell의 prepareForReuse() 메서드를 호출합니다.

 

개별 cell에 Rx를 적용할 경우 prepareForReuse() 함수에서 dispose해줘야하기 때문에 prepareForReuse() 함수를 사용해봤었는데.. 이런 원리로 작동하고 있었군요.


역시 공식문서를 보니 얼레벌레 알고있던 개념을 한 번 잡고 갈 수 있는 것 같습니다.

 

dequeueReusableCell 함수는 뭔가 당연히 cell이 재사용될 때만 불리는거라는 선입견을 갖고 있었는데, 있으면 prepareForReuse를 호출하고 아니면 생성 후 초기화를 한다는 당연한 사실을 새삼스레 깨닫게 되어 다행입니다.