IOS๐ŸŽ/WWDC

[WWDC 2019] Advances in UI Data Sources

Jouureee 2022. 5. 10. 18:56

https://developer.apple.com/videos/play/wwdc2021/10252/

 

Make blazing fast lists and collection views - WWDC21 - Videos - Apple Developer

Build consistently smooth scrolling list and collection views: Explore the lifecycle of a cell and learn how to apply that knowledge to...

developer.apple.com

๋ฅผ ์ฝ๊ธฐ ์ „์— DiffableDataSource์— ๋Œ€ํ•ด ์ดํ•ดํ•˜๊ณ ์ž Advances in UI Data Sources๋ฅผ ๋จผ์ € ๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๋˜ ๋‚ด์šฉ์ด๋ผ ์ญ‰ ํ๋ฆ„์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ฝ๊ณ  2021๋…„๋„์— ๋ฐœํ‘œ๋œ ์„ฑ๋Šฅ ๊ฐœ์„  ์„ธ์…˜๋„ ๋นจ๋ฆฌ ๋ณด๊ณ  ์‹ถ๊ตฐ์š” ใ…Žใ…Ž

 

UICollectionviewDatasource protocol์„ ์ค€์ˆ˜ํ• ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด 3๊ฐœ์˜ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ž‘์„ฑ์ด ๊ฐ„๋‹จํ•˜๊ณ  ์œ ์—ฐํ•˜๊ณ  ์ต์ˆ™ํ•œ ๋ฐฉ์‹์ธ๋ฐ์š”.

๊ทธ์ „์— UI์™€ Controller๊ฐ€ ์„œ๋กœ ์†Œํ†ตํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ด๋ด…์‹œ๋‹ค.

์šฐ์„ , UI layer๊ฐ€ numberOfItemsInSection์„ ํ†ตํ•ด ๋ Œ๋”๋งํ•  item section๊ณผ cell ๋“ฑ์„ ๋‹ฌ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 

 

web service๋กœ๋ถ€ํ„ฐ response๋ฅผ ๋ฐ›์•„์˜ค๊ณ  ์ด๋ฅผ UI์—๊ฒŒ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด UI๋Š” ๋ฐ›์•„๋“ค์ธ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์—…๋ฐ์ดํŠธ ํ• ์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋˜์ฃ .

ํ•˜์ง€๋งŒ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž˜๋ชป๋œ๋‹ค๋ฉด !

โ€‹์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ์ขŒ์ ˆํ•˜๊ณค, reloadData()๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ realodData()์‹œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๊ฐ€ ์—†์„ ๊ฒƒ์ด๋ฉฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ €ํ•˜์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

Data source๋กœ ํ–‰๋™ํ•˜๋Š” controller๋Š” truth์— ๊ณ„์†ํ•ด์„œ ๋ณ€ํ™”ํ•˜๋Š” ์ž์‹ ์˜ ๊ณ ์œ ํ•œ ๋ฒ„์ „์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  UI๋„ truth์— ์ž์‹ ์˜ ๊ณ ์œ ํ•œ ๋ฒ„์ „์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. UILayer ์ฝ”๋“œ๋Š” ํ•ญ์ƒ sync ์ƒํƒœ๋ฅผ ์œ ์ง€ ํ•˜๋„๋ก ํ•˜๋Š” ์ฑ…์ž„์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” Centralized truth๋œ ๊ฐœ๋…์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—, sync๊ฐ€ ๋งž์ง€ ์•Š์•„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 
๊ทธ๋ž˜์„œ ์ƒˆ ์ ‘๊ทผ ๋ฐฉ์‹์ธ Diffable Datasource๋ฅผ ์†Œ๊ฐœํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

 

performBatchUpdates()์™€ ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๊ฐ€ ์—†์œผ๋ฉฐ apply()๋ผ๋Š” ๋‹จ์ผ ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. apply()๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ์ž๋™์œผ๋กœ diffingํ•ฉ๋‹ˆ๋‹ค. 

๊ทธ๋ฆฌ๊ณ  snapshot์ด๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ•˜๋Š”๋ฐ์š”
์ด๊ฒƒ์€ UI state์˜ truth์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  indexpath๋Œ€์‹ , uniqueํ•œ identifier๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

BAR, FOO, BIF๋Š” indentifier๋กœ ํ˜„์žฌ ์ƒํƒœ์—์„œ apply() ํ•˜์—ฌ ์ƒˆ ์Šค๋ƒ…์ƒท์œผ๋กœ ์—…๋ฐ์ดํŠธ ๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด apply()๋Š” ํ˜„์žฌ state์™€ ์ƒˆ state๋ฅผ ์•Œ๊ฒŒ ๋˜๊ณ , ๊ทธ๊ฒƒ์„ UI์— ์—…๋ฐ์ดํŠธ ์‹œํ‚ต๋‹ˆ๋‹ค. 

 

์ด๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค๋Š” 4๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

demo๋ฅผ ๋ณด๋ฉฐ ์ด๋ฅผ ์‚ฌ์šฉํ•ด๋ด…์‹œ๋‹ค. searchBar์— ์‚ฐ ์ด๋ฆ„์„ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์•„๋ž˜ collectionView์—์„œ ์ž๋™์œผ๋กœ filter๋˜๋Š” ์ƒํ™ฉ์„ ๊ตฌํ˜„ํ•ด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋จผ์ € searchBar์— text๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์„ ๊ฐ์ง€ํ•˜๋Š” textDidChange ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. text๊ฐ€ ์ž…๋ ฅ๋˜๋ฉด performQuery(with: searhText)๊ฐ€ ์‹คํ–‰๋˜๊ฒ ์ฃ 
performQuery() ๋ฉ”์†Œ๋“œ๋ฅผ ๋” ์ž์„ธํžˆ ๋ด…์‹œ๋‹ค. 

์šฐ์„  mountainsController.filteredMountains(with: filter)๋ฅผ ํ†ตํ•ด filtering๋œ model data ์ด๋ฆ„ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•ด ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. 
๊ทธ๋ฆฌ๊ณ  3๊ฐ€์ง€ ์Šคํ…์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. 
1. NSDiffableDataSourceSnapshot์„ ์ƒ์„ฑ ํ•ฉ๋‹ˆ๋‹ค. 
2. Snapshot์€ ์ดˆ๊ธฐ์— empty์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์›ํ•˜๋Š” ์„น์…˜๊ณผ ํ•ญ๋ชฉ์œผ๋กœ ์ฑ„์šฐ๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฐ๋ชจ์—์„œ ์šฐ๋ฆฌ๋Š” ๋ณด์—ฌ์ค„ section์ด ํ•˜๋‚˜์ด๋ฏ€๋กœ item์„ ๋‹จ์ผ section์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 
3. ๋‹ค์Œ์œผ๋กœ ์ด ์—…๋ฐ์ดํŠธ์—์„œ ํ‘œ์‹œํ•˜๋ ค๋Š” item์˜ idenfifier๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
4. ๊ทธ๋ฆฌ๊ณ  datasource์—๊ฒŒ ์ด snapshot์„ apply()ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

NSDiffableDataSourceSnapshot์€ Generic Class์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ, ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ Section IdentifierType ๋ฐ Item IdentifierType์— ์˜ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋ฉ๋‹ˆ๋‹ค. 


๋จผ์ €, SectionIdentifierType์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ•˜๋‚˜์˜ ์„น์…˜๋งŒ ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์— ์ •๋ง ํŽธ๋ฆฌํ•œ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. section์€ ์—ด๊ฑฐํ˜•์œผ๋กœ section case๋“ค์„ ๋ช…์‹œํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.



Item IdentifierType์ธ mountains์€ model data์ž…๋‹ˆ๋‹ค. Mountain struct๋Š” hasable๋กœ ๋”ฐ๋กœ identifier๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ mountains๋Š” ๊ฐ๊ฐ์˜ uniqueํ•œ identifier๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 



๊ทธ๋ฆฌ๊ณ  datasource๋ฅผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋„๋ก configureDataSource() ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด ๋†“์•˜์Šต๋‹ˆ๋‹ค.


์ œ ๊นƒํ—™์— ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์˜ฌ๋ ค ๋†“์•˜์Šต๋‹ˆ๋‹ค.

https://github.com/spqjf12345/DiffableDataSource

๋˜ ๋‹ค๋ฅธ ์˜ˆ์‹œ๋ฅผ ๋ด…์‹œ๋‹ค. wifiSettingViewController์ž…๋‹ˆ๋‹ค.
์ด๋ฒˆ์—๋Š” section์ด ๋‘๊ฐœ ์ž…๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์งธ config ์„น์…˜์€ ์™€์ดํŒŒ์ด๋ฅผ ๋„๊ณ  ์ผค ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ ๋ฐ‘์—๋Š” ์—ฐ๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋Š” ์™€์ดํŒŒ์ด๋ฅผ ํƒ์ง€ํ•ด ๋™์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์„น์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. 



๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์„๋•Œ๋งˆ๋‹ค updateUI() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์™€์ดํŒŒ์ด ๋ฒ„ํŠผ์„ ํ† ํด์‹œ์—๋„ ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.



๋งˆ์ฐฌ๊ฐ€์ง€๋กœ snapshot์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฒซ๋ฒˆ์งธ ์„น์…˜์ธ config๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  configItems ์•„์ดํ…œ์„ config ์„น์…˜์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  wifiEnabled ์ƒํƒœ๊ฐ’์ด true๋ผ๋ฉด networks ์„น์…˜์— networkItems์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 
๋„ฃ์–ด์ค€ snapshot์— apply() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด datasource๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด์ค๋‹ˆ๋‹ค. 
์•„๊นŒ์™€ ๋‹ฌ๋ฆฌ UITableViewDiffalbeDataSource์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์–ธ๋œป ๋ณด๊ธฐ์—๋Š” ๋” ๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ํ•ญ๋ชฉ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ๋ณด์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.


์šฐ๋ฆฌ์˜ ๋งˆ์ง€๋ง‰ ์˜ˆ๋Š” ์•„๋งˆ๋„ ๊ฐ€์žฅ ์žฌ๋ฏธ์žˆ๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ƒ‰์ƒ ๊ฒฌ๋ณธ์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•˜๋Š” UICollectionView๊ฐ€ ๋‹ค์‹œ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ๋“ค์€ ์ฒ˜์Œ์— ์ƒ‰์ƒ๋ณ„๋กœ ๋ฌด์ž‘์œ„ ์ˆœ์„œ๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ •๋ ฌ ๋ฒ„ํŠผ์„ ํƒญํ•˜๋ฉด ์ŠคํŽ™ํŠธ๋Ÿผ ์ˆœ์„œ๋กœ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ •๋ ฌ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด ์˜ˆ์ œ๋Š” ์—…๋ฐ์ดํŠธ๋ฅผ ๊ตฌ์„ฑ(construct)ํ•˜๊ณ  ์ปค๋ฐ‹(commit)ํ•˜๋Š” ๋ฐฉ์‹์ด ์ „ ์˜ˆ์ œ์™€ ์•ฝ๊ฐ„ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.  ์ •๋ ฌ ๊ณผ์ •์„ ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š”๋ฐ ์ด ๋ฉ”์„œ๋“œ์—์„œ ์—ฐ์†์ ์ธ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์ด๋•Œ๋งˆ๋‹ค snapshopt์„ ์ƒ์„ฑํ•˜๊ณ  apply() ํ•ฉ๋‹ˆ๋‹ค.
performSortStep() ๋ฉ”์„œ๋“œ๋ฅผ ๋ด ๋ด…์‹œ๋‹ค. ๋ฐ˜๋ณตํ•ด์„œ ์–˜๊ธฐํ–ˆ๋“ฏ์ด 1. Snapshot์„ ์–ป๊ณ  2. ๊ทธ๊ฒƒ์„ populateํ•˜๊ณ  3. Apply ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฒˆ ์˜ˆ์ œ์—์„  ์ƒˆ๋กœ์šด, ๋น„์–ด์žˆ๋Š” snapshot์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ DiffableDataSource์—๊ฒŒ ํ˜„์žฌ์˜ snapshot์„ ์š”์ฒญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.


updateSnapshot์€ ํ˜„์žฌ datasource๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” truth๋กœ ์ฑ„์›Œ์ ธ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
 
์˜ˆ์ „์— ๋ดค๋˜ appendItems() ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๊ณ  ์ถ”๊ฐ€๋กœ deleteItems๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. 


๊ทธ๋ฆฌ๊ณ  dataSource์— updateSnapshot์„ apply ํ•ฉ๋‹ˆ๋‹ค.


๊ทธ๋ฆฌ๊ณค ์—…๋ฐ์ดํŠธ๋œ datasource์— ๋Œ€ํ•ด update UI ํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.


Consideration
reloadData(), intertItems()๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์˜ค์ง apply()๋งŒ์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.



sanpshot์„ ์ƒ์„ฑํ•˜๋Š” ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•


๋”์ด์ƒ indexPath์— ์˜์กดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


์•„์ง๊นŒ์ง€ tableview, collectionviewdatasource๋ฅผ ์จ์˜จ ์‚ฌ๋žŒ์ด ์ฒ˜์Œ diffabledatasource๋ฅผ ๊ณต๋ถ€ํ•ด๋ณธ ๊ฒฐ๊ณผ ๋‹ฌ๋ผ์ง„ ์ ์„ ๊ณ ์ฐฐํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.
์—ฌํƒœ tavleview, collectionvie์˜ indexPath์— ์˜์กดํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์‹ํ•˜๊ณ  UI์— ๋ Œ๋”๋งํ•˜์˜€๋Š”๋ฐ ์ด ์ž‘์—…์— ์˜์กด๋„๋ฅผ ๋‚ฎ์ท„๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. cell์˜ ์‚ญ์ œ ๋ฐ ์ˆ˜์ •, ์ถ”๊ฐ€ ๋“ฑ์˜ ์ž‘์—…์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ด๋ค„์งˆ ๊ฒฝ์šฐ cell์— ๊ฐœ๋ณ„ indexpath ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๊ฐ๊ฐ์˜ cell์„ ๊ตฌ๋ถ„ํ•˜์˜€๋‹ค. ํ•˜์ง€๋งŒ ์ด์ œ indexpath๊ฐ€ ์•„๋‹Œ model data๊ฐ€ Hashable ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜์—ฌ ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ตฌ๋ณ„ํ•  identifier๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด๋„๊ฐ€ ๋‚ฎ์•„์งˆ๊ฒƒ ๊ฐ™๋‹ค. ๋”์šฑ์ด ๋งˆ๋ฒ• ๋ฉ”์†Œ๋“œ(reloadData)๋ฅผ ๋” ์ด์ƒ ์“ฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์ ์ด ์‹œ์Šคํ…œ์— ๋ถ€๋‹ด์ด ๋œ์–ด์งˆ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ์„ฑ๋Šฅ์€ 2021 WWDC ์˜์ƒ์„ ๋ด์•ผ ์•Œ๊ฒ ์ง€๋งŒ ํํ 3๊ฐ€์ง€ ๋‹จ๊ณ„๋งŒ ์ง€ํ‚จ๋‹ค๋ฉด controller์™€ UI ๊ฐ„์˜ sync๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์  ๋“ฑ๋“ฑ์—์„œ ํšจ์œจ์ ์ธ ๊ฐœ์„ ์ฑ…์ด๋ผ๊ณ  ์ƒ๊ฐ ๋“ค์—ˆ๋‹ค. 


Main queue์—์„œ ๋ฒ—์–ด๋‚˜ Background queue์—์„œ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ ์•ˆํ–ˆ๋‹ค๊ณ  ํ•˜์‹ ๋‹ค .. !  ํ•˜์ง€๋งŒ Main queue์—์„œ๋งŒ ๋˜๋Š” Background queue์—์„œ๋งŒ ๋ฐฐํƒ€์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค ์•ˆ๊ทธ๋Ÿฌ๋ฉด log ์ฐํž ๊ฒƒ 



์ถ”๊ฐ€) Airdrop extension์— ์‚ฌ์šฉ๋จ !!