๊ธ€ ์ž‘์„ฑ์ž: ๊ฐœ๋ฐœํ•˜๋Š” ํ›ˆ์ด

2022.01.14 ์˜ค๋Š˜์˜ ๋ฐฐ์›€

์˜ค๋Š˜ ํ•œ ์ผ.

  • ์Šค๋…ธ์šฐ ์ฝ”ํ…Œ๋ณด๊ธฐ
  • ์ด๋ฒˆ ์ฃผ์— ๋ฉด์ ‘๋ณธ ๋‘ ๊ณณ ๋ฉด์ ‘ ๋ณต๊ธฐ
  • naljin๋‹˜ gcd ํฌ์ŠคํŠธ ์ญ‰ ๋‹ค์‹œ ์ฝ์–ด๋ณด๊ธฐ - ํ•ญ์ƒ ๋Š๋ผ์ง€๋งŒ ๊ธ€์„ ์ง„์งœ๋กœ ์ž˜ ์“ฐ์‹ ๋‹ค.. ๊ฐ€๋ฒผ์šด๋“ฏํ•˜๋ฉด์„œ ํ•„์š”ํ•œ ๋‚ด์šฉ์€ ๋ชจ๋‘ ์ „๋‹ฌํ•˜์‹ ๋‹ค. ๋ณธ๋ฐ›๊ณ  ์‹ถ์€ ํฌ์ŠคํŒ… ์‹ค๋ ฅ..
 

[iOS] ์ฐจ๊ทผ์ฐจ๊ทผ ์‹œ์ž‘ํ•˜๋Š” GCDโ€Š—โ€Š1

์ด๋ฒˆ์—” ์ œ๋ฐœ ์ดํ•ดํ•˜๊ณ  ์‹ถ๋‹ค GCD..๐Ÿฅ‚

sujinnaljin.medium.com

  • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ UI๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๋Š” ์ด์œ  ์ฝ์–ด๋ณด๊ธฐ - ์•ฝ๊ฐ„ ๋กœ์šฐ๋ ˆ๋ฒจ ๊ฐœ๋…์ด ์„ž์—ฌ์žˆ์–ด์„œ ์‰ฝ์ง€๋Š” ์•Š๋‹ค.
 

iOS: Why the UI need to be updated on Main Thread

Do you ever think about why UI really MUST to be updated on main thread? What will happened if we turn UIKit into thread-safe design?

medium.com

์˜ค๋Š˜ ์ƒˆ๋กœ ๋ฐœ๊ฒฌํ•œ ๊ฒƒ.

  • ๋ณด๋ผ์ƒ‰์œผ๋กœ ์˜ค๋ฅ˜๋œจ๋Š”๊ฑด Main Thread Checker๊ฐ€ ์žก์•„์ฃผ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.. ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋Œ๋ฉด ์•ˆ๋˜๋Š” ์ž‘์—…์„ ์žก์•„์ฃผ๋Š” XCode์˜ ๊ธฐ๋Šฅ์ด๋‹ค.
  • ๋ณดํ†ต ๊ฐ™์€ ํ์—์„œ ๊ฐ™์€ ํ๋กœ sync ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฐ๋“œ๋ฝ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์•Œ๊ณ ์žˆ๋Š”๋ฐ, QoS๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ฃผ๋ฉด QoS๋งˆ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด์„œ ๋ฐ๋“œ๋ฝ์ด ์•ˆ๋‚œ๋‹ค๊ณ  ํ•œ๋‹ค.
  • ํด๋กœ์ €์—์„œ ํด๋กœ์ € ์™ธ๋ถ€์˜ ์ •๋ณด(self ํฌํ•จ)์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ•ํ•œ ์ฐธ์กฐ๋กœ ์บก์ณ๋œ๋‹ค. weak self ์“ฐ๋Š”๊ฒŒ ์ด๊ฑธ ์•ฝํ•œ ์ฐธ์กฐ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.
  • DispatchGroup์„ ์“ธ ๋•Œ, notify๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„, ๊ทธ๋ฃน์— wait์„ ๊ฑธ์–ด์„œ ๊ทธ๋ฃน์„ ๋งŒ๋“  ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ ๋ธ”๋ก์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์— ํƒ€์ž„์•„์›ƒ์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ฃผ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ํƒ€์ž„์•„์›ƒ์ด ์ธ์ž๋กœ ๋“ค์–ด๊ฐ€๋ฉด wait์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์€ DispatchTimeoutResult ๊ฐ€ ๋œ๋‹ค. Result ๊ฐ์ฒด์ฒ˜๋Ÿผ success, failure๋กœ ์ ‘๊ทผํ•˜๊ณ  ์ง€์ •ํ–ˆ๋˜ ์‹œ๊ฐ„์•ˆ์— ์ž‘์—…๋“ค์ด ๋ชจ๋‘ ๋๋‚˜๋ฉด success, ๋๋‚˜์ง€ ์•Š์€ ์ž‘์—…์ด ์žˆ์œผ๋ฉด failure๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค. 
  • ์ด๋•Œ wait์„ ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋ก๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์—ฐํžˆ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ๋Š” ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
  • ๊ทธ๋ฃน ์•ˆ์— ๋น„๋™๊ธฐ ์ž‘์—…์ด ์—†์œผ๋ฉด ๊ทธ๋ƒฅ async์— ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ group์„ ์ฃผ๋ฉด ๋˜์ง€๋งŒ, ๋น„๋™๊ธฐ ์ž‘์—…์ด ์žˆ์œผ๋ฉด ๋น„๋™๊ธฐ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— enter, ๋๋‚˜๋ฉด completion์—์„œ leave๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ group์— ์ž‘์—…์ด ๋๋‚ฌ์Œ์„ ์•Œ๋ ค์•ผํ•œ๋‹ค. 
  • DispatchWorkItem์œผ๋กœ ์บก์Šํ™”ํ•œ ์ž‘์—…์€ async(execute: )์œผ๋กœ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, .perform์œผ๋กœ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์—์„œ syncํ•˜๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • DispatchWorkItem์˜ cancel์„ ํ˜ธ์ถœํ•˜๋ฉด ์ž‘์—…์ด ์•„์ง ํ์—์„œ ๋Œ€๊ธฐ์ค‘์ผ ๋•Œ๋Š” ์ž‘์—…์ด ์ทจ์†Œ๋˜์ง€๋งŒ, ์ด๋ฏธ ์‹œ์ž‘ํ•œ ์ž‘์—…์€ ํ”Œ๋ž˜๊ทธ๋งŒ ๋ฐ”๊พธ๊ณ  ์ž‘์—…์ด ์ค‘๋‹จ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.
  • ์ž‘์—…๊ฐ„์˜ ์˜์กด์„ฑ์„ ๋งŒ๋“ค๋ ค๋ฉด OperationQueue๊ฐ€ ์ œ์ผ ๊น”๋”ํ•˜๊ธด ํ•˜์ง€๋งŒ, DispatchSemaphore๋กœ ์ˆœ์„œ๋ฅผ ๋งž์ถ”๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋Œ€์‹  ์ด๋Ÿฌ๋ฉด ์‚ฌ์‹ค์ƒ ์‹œ๋ฆฌ์–ผ ํ์— sync๋กœ ์ž‘์—…์„ ๋ณด๋‚ด๋Š”๊ฑฐ๋ž‘ ๋ณ„๋กœ ๋‹ค๋ฅผ๊ฒŒ ์—†์„ ๊ฒƒ ๊ฐ™๋‹ค.
  • ๊ฒฝ์Ÿ์ƒํƒœ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด barrier ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์“ฐ๊ธฐ์ž‘์—…์€ barrier๋กœ ์‹œ์ž‘ํ•ด์„œ ์“ฐ๊ธฐ๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๋™์•ˆ์—๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์“ฐ๊ธฐ์ž‘์—…์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ํ•˜๊ณ , ์ฝ๊ธฐ ์ž‘์—…์€ ์ž์œ ๋กญ๊ฒŒ ๊ณต์œ ์ž์›์— ์ ‘๊ทผํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • barrier ๋ธ”๋Ÿญ์ด ์‹œ์ž‘๋˜๋ฉด ๋‹ค๋ฅธ ์• ๋“ค์ด ์ž‘์—…์„ ๋ฉˆ์ถ”๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ๊ธฐ์กด์— ์ž‘์—…์ค‘์ด๋˜ ์• ๋“ค์ด ์ข…๋ฃŒ๋˜๋ฉด ๊ทธ๋•Œ์„œ์•ผ barrier๋ฅผ ์ค€ ๋ธ”๋Ÿญ์„ ์‹คํ–‰ํ•œ๋‹ค.
  • barrier๋ฅผ ์“ฐ๋ ค๋ฉด async(flags: .barrier, execute: {Task}) ๋กœ ์ฃผ๋ฉด๋œ๋‹ค.
  • var name: String {
      get {
        self._name
      }
      set {
        concurrentQueue.async(flags: .barrier, execute: {
          self._name = newValue
          print(self._name)
        })
      }
    }
  • ๋ฐ๋“œ๋ฝ์„ ๋ง‰์œผ๋ ค๋ฉด ๊ทธ๋ƒฅ ์‹œ๋ฆฌ์–ผ ํ๋ฅผ ์“ฐ๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿผ ๋ฌด์กฐ๊ฑด ํ•œ๋ฒˆ์— ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰๋˜๋‹ˆ๊นŒ. ๊ทผ๋ฐ ๊ทธ๋ ‡๋‹ค๊ณ  ๋ฌด์กฐ๊ฑด ์‹œ๋ฆฌ์–ผ ํ๋งŒ ์“ฐ๋ฉด ์„ฑ๋Šฅ์— ์†ํ•ด๋ฅผ ๋ณด๋‹ˆ๊นŒ ์„ค๊ณ„๊ฐ€ ์ž˜ ๋˜์–ด์žˆ๋Š”์ง€ ๋ณด๋ฉด์„œ ์ ์ ˆํ•˜๊ฒŒ ๋Œ€์‘ํ•ด์•ผํ•œ๋‹ค.
  • Priority Inversion์€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์€ ํƒœ์Šคํฌ๊ฐ€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ํƒœ์Šคํฌ๊ฐ€ ํ•„์š”ํ•œ ์ž์›์„ ์ ์œ ํ•˜๊ฒŒ ๋˜๋ฉด์„œ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋’ค์ง‘ํ˜€๋ฒ„๋ฆฌ๋Š” ์ƒํ™ฉ์„ ๋งํ•œ๋‹ค.
  • ์‹ค์ œ๋กœ๋Š” ์‹œ๋ฆฌ์–ผ ํ์—์„œ qos๊ฐ€ ๋‚ฎ์€ ํƒœ์Šคํฌ๊ฐ€ ๋จผ์ €๋“ค์–ด์˜จ ๋’ค์— qos๊ฐ€ ๋†’์€ ํƒœ์Šคํฌ๊ฐ€ ๋“ค์–ด์™€์„œ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์˜๋ฏธ์—†์–ด์ง€๋Š” ์ƒํ™ฉ์ด๋‚˜,  Operation queue์—์„œ qos๊ฐ€ ๋†’์€ ํƒœ์Šคํฌ๊ฐ€ qos๊ฐ€ ๋‚ฎ์€ ํƒœ์Šคํฌ์˜ ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ฒŒ ๋  ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • low, mid, high ์ˆœ์œผ๋กœ ์ž‘์—…์ด ๋„์ฐฉํ•˜๊ณ , low๊ฐ€ high์—์„œ ํ•„์š”ํ•œ ์ž์›์„ ์ ์œ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, high๊ฐ€ ์‹œ์ž‘๋˜์–ด์„œ CPU๋ฅผ ์„ ์ ํ•˜๋ฉด low๊ฐ€ ๋๋‚˜๊ธธ ๊ธฐ๋‹ค๋ฆฌ๋ฉด์„œ ๋Œ€๊ธฐํ•˜๊ฒŒ ๋˜๊ณ , ๋‹ค์Œ ์šฐ์„ ์ˆœ์œ„์ธ mid๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๊ณ  ์ข…๋ฃŒ๋œ๋‹ค. high๋Š” low๋ณด๋‹ค ๋ฌด์กฐ๊ฑด ๋Šฆ๊ฒŒ ๋๋‚˜์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— mid->low->high ์ˆœ์œผ๋กœ ์ž‘์—…์ด ์ฒ˜๋ฆฌ๋œ๋‹ค. 
  • GCD์—์„œ๋Š” ์ด๊ฑธ ๋ง‰์œผ๋ ค๊ณ  ๊ทธ๋ƒฅ ์ž์›์„ ์ ์œ ํ•˜๋Š” ์Šค๋ ˆ๋“œ์˜ qos๋ฅผ ์ž„์‹œ์ ์œผ๋กœ ๋†’์—ฌ๋ฒ„๋ฆฐ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์œ„์—๋ž‘ ๋˜‘๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ๋„ high๊ฐ€ ๋“ค์–ด์™€์„œ low์˜ ์ž์›์„ ์œ„ํ•ด ๋Œ€๊ธฐํ•  ๋•Œ, GCD๊ฐ€ low์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ high๋กœ ์˜ฌ๋ ค๋ฒ„๋ ค์„œ ๋‚จ์€ ์ž‘์—…์„ ๋‹ค ์ฒ˜๋ฆฌํ•˜๊ณ , low๊ฐ€ ๋๋‚˜๋ฉด high๊ฐ€ ์‹คํ–‰๋˜๋ฏ€๋กœ low->high->mid ์ˆœ์œผ๋กœ ์‹คํ–‰๋˜์–ด์„œ ์„œ๋กœ ์˜์กด๊ด€๊ณ„๊ฐ€ ์—†๋Š” high์™€ mid์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์—ญ์ „๋˜์ง€ ์•Š๋Š”๋‹ค.

์˜ค๋Š˜ ๋Š๋‚€ ๊ฒƒ.

  • ๊ฐ€์žฅ ๊ฐ€๊ณ ์‹ถ๋˜ ๊ธฐ์—…์˜ ์ตœ์ข…๋ฉด์ ‘์„ ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ์ตœ์ข…์„ ๋ณธ๋‹ค๋Š” ๊ฒƒ๋„ ์–ผ๋–จ๋–จํ•œ๋ฐ ๋‹ค์‹œ ๋˜ CS๋ž‘ ํ”Œ์ ์ด๋ž‘ Rx๋ž‘ ์ค€๋น„ํ•˜๊ณ  ๋ฉด์ ‘๊ฐ€์„œ ์˜ํ˜ผํƒˆ๊ณก ๋‹นํ•  ๊ฑธ ์ƒ๊ฐํ•˜๋‹ˆ ๋„ˆ๋ฌด๋„ˆ๋ฌด ๋ฌด์„ญ์ง€๋งŒ ๊ทธ๋ž˜๋„ ์ตœ์„ ์„ ๋‹คํ•ด๋ด์•ผ๊ฒ ๋‹ค.
  • ์Šค๋…ธ์šฐ ์ฝ”ํ…Œ๋Š” ์•ž ๋‘ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฐํ•œ๋Œ€๋กœ ๋„ˆ๋ฌด ์ž˜ ํ’€๋ ค์„œ ๊ธฐ๋ถ„ ์ข‹์•˜๋Š”๋ฐ, ๋งˆ์ง€๋ง‰ ๋ฌธ์ œ์—์„œ ์‹œ๊ฐ„์„ ๋„ˆ๋ฌด ๋งŽ์ด ์žก์•„๋จน์–ด์„œ ํ•ด๊ฒฐ์„ ๋ชปํ–ˆ๋‹คใ…  ์ด๊ฒƒ๋„ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ ค๋ณด์ž!
  • ๋ฉด์ ‘์„ ๋ณต๊ธฐํ•˜๋ฉด์„œ ๊ฐ€์žฅ ๋งŽ์ด ๋“  ์ƒ๊ฐ์€ "์•„ ๋” ๋‚˜์€ ๋Œ€๋‹ต์ด ์žˆ์—ˆ๋Š”๋ฐ ์™œ ๊ทธ๋ ‡๊ฒŒ ๋งํ–ˆ์ง€?"์˜€๋‹ค.. ํ•˜๋‹ค๋ณด๋ฉด ์ ์  ๋‚˜์•„์ง€๊ฒ ์ง€?
  • ์ „ํ˜•์˜ ๊ฒฐ๊ณผ๋“ค์ด ์กฐ๊ธˆ์”ฉ ๋‚˜์˜ค๋ฉด์„œ ๊ธด์žฅ์ด ํ’€๋ ธ๋Š”์ง€ ์–ด์ œ ์˜ค๋Š˜์€ ๊ณ„์† ์ž ์„ ๋งŽ์ด ์žค๋‹ค.. ๋‚ด์ผ๋ถ€ํ„ฐ๋Š” ๋‹ค์‹œ ์ง‘์ค‘์„ ํ•ด๋ณด์ž!

๋‚ด์ผ์˜ ๊ณ„ํš.

  • ๋ฉด์ ‘์ค€๋น„. ์ด์ œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณด๋Š” ์ „ํ˜•์€ ๋‹ค ๋๋‚˜์„œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ฉˆ์ถ”๊ณ  ๋‹ค์‹œ CS, iOS, Rx, ํ”Œ์  ์ •๋ฆฌ๋ฅผ ํ•ด์•ผํ•  ๊ฒƒ ๊ฐ™๋‹ค.

์˜ค๋Š˜์˜ ๊ฐ์‚ฌ.

  • ์ง„์งœ๋กœ ๋‹ค ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋งˆ์ง€๋ง‰๊นŒ์ง€ ์–ด๋–ป๊ฒŒ ๋˜๋“  ์ง€๊ธˆ๊นŒ์ง€์˜ ๋…ธ๋ ฅ์„ ์ด๋ ‡๊ฒŒ๋ผ๋„ ์ธ์ •๋ฐ›๊ฒŒ ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ด์š”!