tableView에서 Cell을 재사용하기 위해 사용되는 메서드인 dequeueReusableCell에는 두가지 형태가 있습니다.
dequeueReusableCell(withIdentifier:for:)과 dequeueReusableCell(withIdentifier:)가 그것인데요.
이 두 메서드의 정확한 차이는 무엇일까요? 하나는 indexPath를 함께 파라미터로 받고 있고, 하나는 받지 않고 있습니다. 두 메서드의 기능이 똑같다면 굳이 indexPath 넣어주는 메서드를 사용할 필요가 있을까요? 무언가 특별한 기능이 있으니까 사용하는 것 아닐까요?
일단 애플 공식문서 찾아보기
일단 문서의 글을 읽어봅시다.
- func dequeueReusableCell(withIdentifier:for:) : reuse identifier에 의해 확인된 재사용 가능한 TableView의 cell을 리턴하고 이를 table에 추가합니다.
- func dequeueReusableCell(withIdentifier:) : identifier에 의해 확인된 재사용 가능한 TableView의 cell을 배치하고 리턴합니다.
음... 글만 봐서는 딱히 차이점을 알 수가 없네요. 그런데 자세히보면 dequeueReusableCell(withIdentifier:for:)는 리턴값은 옵셔널타입이 아니고, dequeueReusableCell(withIdentifier:)는 옵셔널타입이예요!
이를 통해 dequeueReusableCell(withIdentifier:for:)은 identifier로 받아올 수 있는 값이 없으면 터지고 dequeueReusableCell(withIdentifier:)는 이에 대한 처리를 해줄 수 있음을 알 수 있어요.
그럼 dequeueReusableCell(withIdentifier:for:)가 구형메서드이고 dequeueReusableCell(withIdentifier:)는 앱이 터지는 것을 방지할 수 있도록 새롭게 만들어진 메서드인 것일까요?
놀랍게도 아닙니다! 공식문서를 보면 dequeueReusableCell(withIdentifier:for:)가 더 나중인 iOS 6.0에서 업데이트되었음을 알 수 있어요. 아니 그럼 도대체... 이것이 뭐가 좋길래 옵셔널이 아닌 값으로 앱을 터트릴 위험도 있는 주제에 indexPath까지 필요한 것일까요?
연구끝에 내린 결론
자 결론부터 말씀드리겠습니다. dequeueReusableCell(withIdentifier:for:)을 통해 받아온 cell은 현재 TableView의 size 정보를 바로 가지고 있는 반면 dequeueReusableCell(withIdentifier:)의 통해 받아온 cell은 size 정보를 가지고 있지 않습니다. 이를 코드로 확인해보겠습니다.
extension ViewController: UITableViewDataSource {
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellWithIndexPath = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
guard let cellWithOutIndexPath = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell") else { return UITableViewCell() }
print("\(indexPath.row) WithIndexPath : \(cellWithIndexPath.frame.size)")
print("\(indexPath.row) WithOutIndexPath : \(cellWithOutIndexPath.frame.size)")
return cellWithIndexPath
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 30
}
}
일단 위 코드의 cellWithIndexPath는 dequeueReusableCell(withIdentifier:for:)을 통해 cell을 받아오고 있고, cellWithOutIndexPath는 dequeueReusableCell(withIdentifier:)를 통해 cell을 받아옵니다. 이 둘의 frame.size값을 한번 비교해봅시다. 실행해보면?
오... IndexPath를 지정해준 cell은 TableView의 size값 (388.0, 30.0)을 제대로 가지고 있는 반면에 IndexPath없이 받아온 cell은 기본값으로 추정되는 (320.0, 44.0)를 가지고 있네요. 그렇다고 화면 출력이 이상하게 되는 것은 아니예요. 화면 출력에는 둘 모두 (388.0, 30.0) size로 제대로 출력됩니다. 아마 IndexPath없이 받아온 cell의 경우 추후 처리를 통해 그 때 size가 결정되는 것 같습니다.
재활용 cell을 받아오자마자 이에 대한 size값을 필요로 하는 경우, dequeueReusableCell(withIdentifier:for:)로 IndexPath와 함께 cell을 받아와야겠네요!
정리
자자 마지막으로 표로 비교해보며 정리해봅시다
dequeueReusableCell(withIdentifier:for:) | dequeueReusableCell(withIdentifier:) | |
IndexPath | 필요함 | 필요없음 |
리턴값 옵셔널 | 옵셔널아님 | 옵셔널임 |
가져온 Cell Size | 해당 tableView에 맞춰짐 | default (320.0, 44.0) |
끝!!
'🍎 Apple > Question' 카테고리의 다른 글
[iOS] Remote data를 가져올 때 Data(contentsOf:)를 사용하면 안되는 이유 (1) | 2022.05.17 |
---|---|
[iOS] #selector는 무엇이며 왜 필요할까? (0) | 2022.02.07 |
[iOS] 왜 오토 레이아웃을 사용할 때는 translatesAutoresizingMaskIntoConstraints = false를 할까? (0) | 2022.01.21 |
[iOS] 왜 UI는 메인 스레드에서 다룰까? (2) | 2022.01.14 |