-
Notifications
You must be signed in to change notification settings - Fork 1
❗ 테이블 뷰가 보고 있는 배열과 bind하고 있는 배열 간의 race condition 문제
UIKit에서 테이블 뷰는 DataSource가 변하더라도 뷰가 업데이트 되지 않는다.
그러므로, 일일히 업데이트 해주어야 한다.
이런 식으로 테이블 뷰가 보고 있는 DataSource의 변화를 모두 reload해주는 함수이다.
reloadData는 뷰를 아예 새로 그려버리기 때문에 성능적 부하가 크다.
셀 1개만 바뀌어도 모든 셀을 다시 그려버릴 순 없지 않은가?
viewModel.$currentRecords
.receive(on: DispatchQueue.main)
.sink { [weak self] records in
guard let self, !records.isEmpty else { return }
let indexPath = IndexPath(row: records.count - 1, section: 0)
self.resultTableView.insertRows(at: [indexPath], with: .fade)
이런 식으로 record가 변화할 때마다 추가 된 것이므로, 테이블 뷰에 row 자체를 추가하게 만들어주었다.
이미 추가된 셀에 insert할 수 없습니다
라는 느낌의 오류를 받게 되었다.
테이블 뷰에서 currentRecords 변화를 알고 row를 생성하는 시점과 currentRecords를 bind해서 insertRows하는 시점 간에
테이블 뷰에서 먼저 row를 생성하게 되면 insertRows는 이미 들어간 row를 접근하게 되기 때문에 생기는 문제이다.
viewModel.$currentRecords
.receive(on: DispatchQueue.main)
.sink { [weak self] records in
guard let self, !records.isEmpty else { return }
let indexPath = IndexPath(row: records.count - 1, section: 0)
if records.count > resultTableView.numberOfRows(inSection: 0) {
resultTableView.insertRows(at: [indexPath], with: .fade)
}
else {
resultTableView.reloadRows(at: [indexPath], with: .fade)
}
}
.store(in: &cancellables)
먼저 테이블 뷰의 row 개수 여부를 확인하고 currentRecords 개수와 비교해서
테이블 뷰의 row개수가 더 적다면 insertRows.
row가 이미 있다면 reloadRows로 방어 로직을 작성해주었다.
이렇게 하면 이미 row가 있다면 insert와 같은 raceCondition 문제를 막을 수 있지... 않다...
아주 낮은 확률이나, resultTableView의 Row개수가 records의 개수랑 비교했을 때 작다는 걸 확인한 그 순간에
Row가 생성되어 Data-Race가 발생하게 된다.
그로 인해 해당 Row 자리에는 이미 Row가 있어 insertRows시 에러가 발생하게 된다.
DiffableDataSource를 이용하면 된다.
간단히 말하자면, snapShot을 통해 들어온 데이터로 테이블 뷰를 구성하고,
이후에 snapShot으로 새로운 데이터가 들어왔을 때, 이전에 찍어주었던 snapShot과 비교하여 새로 들어오거나 변화된 데이터에 대해서만 reload를 진행한다.
마치 reloadData와 동일하게 동작하나, 효율적으로 움직인다고 볼 수 있다.
- 📒 기획의 과정과 의도
- 📒 swift6 도입기 ‐ @unchecked Sendable을 사용해야만 했던 이유
- 📒 WaveForm(파형) 제작기
- 📒 프로젝트 구조와 이유
- 📒 화면 전환(Game NavigationController)
- 📒 DIContainer를 사용한 계기
- 📒 AudioHelper 제작기
- 📒 음악 플레이어의 compact 버전 제작기
- 📒 Combine을 이용한 데이터 전달
- 📒 파이어베이스를 쓰며 있었던 일
- 📒 캐싱 모듈 구현과 문제점
- 📒 로그 시스템 제작기
- ❗ Data 끼리의 비교
- ❗ 프레임워크 Reference 안잡히는 문제
- ❗ actor 안에서 timer가 실행되지 않는 문제
- ❗ NSLayoutConstraint 옵셔널 문제
- ❗ 테이블 뷰가 보고 있는 배열과 bind하고 있는 배열 간의 race condition 문제
- ❗ 테스트끼리의 독립성
- ❗ 네트워크 테스팅 시 Error 핸들링
- ❗ 여러 클라이언트가 서버에 동시 요청시, 데이터가 반영이 안되는 이슈 해결
- ❗ 의존성 framework 추가시 불러오지 못하는 문제
- ❗ Timer를 6초 설정해도 더 실행되는 문제
- ❗ Music Kit Data Request 에러
- ❗ DI Container 에서 생성한 인스턴스가 동시에 존재 하는 이슈