티스토리 뷰
Diffable Data Source in iOS 15 에서 다룬 내용인데, 헷갈리니까 한번 더 정리!
[1] UITableViewDiffableDataSource의 4가지 apply 메서드들
UITableViewDiffableDataSource 에는 Updating Data를 위한 4개의 apply 메서드들이 있습니다.
위에서부터 적어보면 다음과 같습니다.
- apply(_:animatingDifferences:) // iOS 15+
- apply(_:animatingDifferences:completion:) // iOS 13+
- applySnapshotUsingReloadData(_:) // iOS 15+
- applySnapshotUsingReloadData(_:completion:) // iOS 15+
[2] 각각 살펴보기
4개 중, 하나만 iOS 13부터 쓸 수 있으므로 이것을 먼저 살펴보겠습니다.
[2.1] apply(_:animatingDifferences:completion:)
# 문서
✔️ snapshot의 데이터 상태를 반영하도록 UI를 업데이트한다.
✔️ animatingDifferences가 true면 테이블뷰를 에니메이팅하며 업데이트하고 false면 애니메이션 안한다.
✔️ 업데이트가 끝나면 completion handler가 실행된다. 시스템은 이 클로저를 main queue에서 콜한다.
✔️ diffable data source는 tableview의 current state와 new state를 차이(diff) 를 계산하는데, 이것은 O(n)의 시간복잡도를 가진다. (n은 snapshot에 있는 item 갯수)
✔️ background queue에서 이 메소드를 콜해도 안전하지만, 항상 main queue에서 부르던가 background queue에서 부르던가 하나만 하라.
# 예제
간단히 예제를 작성해보겠습니다.
돌려보면 아래와 같고
콘솔 출력은 이렇게 됩니다.
// print
applyInitialSnapshot() completion called
applyNewSnapshot() completion called
그럼 똑같은 snapshot을 apply해도 completion이 불릴까요?
맞습니다! 이렇게 바꿔서 돌려봐도
func applyNewSnapshot() {
dataSource.apply(dataSource.snapshot(), animatingDifferences: true) {
print(#function + " completion called")
}
}
똑같이 출력되는 것을 볼 수 있습니다.
// print
applyInitialSnapshot() completion called
applyNewSnapshot() completion called
[2.2] apply(_:animatingDifferences:)
이제부터 iOS 15 부터 쓸 수 있는 apply 메서드들을 살펴보겠습니다.
# 문서
위의 메서드와 다른 점은 completion이라는 파라미터가 빠지고 뒤에 async가 붙었다는 점입니다.
문서에 별도 설명은 없습니다.
애플이 왜 iOS 15에 이것을 추가했을까요?
그 이유는 WWDC 2021 > Make blazing fast lists and collection views 에서 알 수 있습니다.
위에서 살펴본 apply(_:animatingDifferences:completion:)는
모든 경우, 이전 snapshot과 변경된 snapshot을 비교해서 diff만 업데이트하는게 아닙니다!!!
animatingDifferences에 어떤 값을 넘겨주는 가에 따라서 다르게 동작합니다.
1) animatingDifferences 파라미터에 true를 넘기면 diff만 딱 업데이트.
2) animatingDifferences 파라미터에 false를 넘기면 내부적으로 reloadData로 바뀌어서 동작.
즉 animatingDifferences에 true를 넘겨야지만 diff만 딱 업데이트합니다.
근데 이거 예측하기 너무 어렵지 않나요....?...
그래서인지.. 애플은
iOS 15에서는 animatingDifferences 값과 상관없이
오직 difference만 적용하고 다른 extra work는 하지 않는 API를 추가했다고 합니다.
정리하자면..
✔️ apply(_:animatingDifferences:completion:) // iOS 13
=> animatingDifferences가 true일때만 diff만 업데이트. false면 reloadData로 동작.
✔️ apply(_:animatingDifferences:) // iOS 15
=> animatingDifferences에 상관없이 항상 diff만 업데이트.
great performance 를 위해 apply(_:animatingDifferences:) 를 쓰는 게 더 좋습니다.
이를 위해 별도 코드수정 작업을 해줘야하는 것이 아니라 iOS 15에서 알아서 됩니다.
왜냐면..
apply(_:animatingDifferences:completion:) 의 completion 디폴트 값이 nil로 되어있기 때문에
아래와 같이 코드를 작성하면 두개의 함수 시그니처가 같으므로
dataSource.apply(snapshot, animatingDifferences: true)
iOS 13, 14에서는 apply(_:animatingDifferences:completion:) 로 불리고
iOS 15에서는 apply(_:animatingDifferences:) 로 불립니다.
실제 시뮬레이터 버전을 다르게 해서 돌려보면
iOS 13,14 와 iOS 15가 다르게 동작하는 것을 확인하실 수 있습니다.
[2.3] applySnapshotUsingReloadData(_:)
# 문서
✔️ diff를 계산하지 않고 reloadData한다.
(위의 맥락과 이어집니다.
apply가 diff만 업데이트하도록 바뀌었기때문에 reload를 하고 싶을때를 위한 메서드를 제공해줬습니다.
diff만 업데이트 하는게 아니라 reload 를 하고 싶은면 이 메소드를 콜해주면 됩니다.)
✔️ 시스템은 진행 중인 모든 아이템 애니메이션을 중단하고 테이블뷰를 즉시 다시 reload 한다.
✔️ background queue에서 이 메소드를 콜해도 안전하지만, 항상 main queue에서 부르던가 background queue에서 부르던가 하나만 하라.
[2.4] applySnapshotUsingReloadData(_:completion:)
# 문서
applySnapshotUsingReloadData(_:) 과 똑같은데 completion 파라미터만 추가적으로 있는 것입니다.
시스템은 completion 클로저를 main queue에서 콜합니다.
'🍏 > iOS' 카테고리의 다른 글
[iOS] Swift Package 에서 RELEASE Flag 사용하기 (0) | 2022.07.04 |
---|---|
[iOS] DiffableDataSource 헷갈리는 것 정리 (1) | 2022.06.29 |
[iOS] Edit Menus (UIMenuController) 커스터마이징 (2) | 2022.06.03 |
[iOS] RxSwift 로 살펴보는 써드파티 라이브러리 5가지 사용 방법 (0) | 2022.03.12 |
[iOS] Overriding Build Settings for a Target 원복하기 (0) | 2022.02.08 |
- Total
- Today
- Yesterday
- 구글 Geocoding API
- Watch App for iOS App vs Watch App
- flutter deep link
- PencilKit
- Flutter 로딩
- Python Type Hint
- ipad multitasking
- Django Heroku Scheduler
- DRF APIException
- flutter 앱 출시
- METAL
- Flutter Spacer
- SerializerMethodField
- Dart Factory
- ribs
- Flutter getter setter
- cocoapod
- Django Firebase Cloud Messaging
- 플러터 싱글톤
- 장고 Custom Management Command
- Sketch 누끼
- github actions
- 플러터 얼럿
- drf custom error
- flutter build mode
- 장고 URL querystring
- Django FCM
- Flutter Text Gradient
- flutter dynamic link
- Flutter Clipboard
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |