DispatchQueue πŸ“™

YaR LabΒ·2023λ…„ 7μ›” 13일
0

swiftΒ πŸ“™

λͺ©λ‘ 보기
6/16
post-thumbnail

1️⃣ μ„€λͺ…

  • GCDλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•œ λŒ€κΈ°μ—΄λ‘œ, GCD기술의 일뢀

    GCD (Grand Central Dispatch)

    • λ©€ν‹°μ½”μ–΄ μ‹œμŠ€ν…œμ—μ„œ λ™μ‹œμ„± 싀행을 μ œκ³΅ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ μš”μ†Œ, λŸ°νƒ€μž„ 라이브러리 λ“±
    • GCDλŠ” DispatchQueue보닀 넓은 κ°œλ…
    • GCDλŠ” DispatchλΌλŠ” ν”„λ ˆμž„μ›Œν¬μ™€ λ™μΉ˜μ‹œν‚¬ 수 있음
  • FIFO(First In, First Out)둜 μž‘μ—…μ„ 처리
  • DispatchQueueλ₯Ό μ»€μŠ€ν…€ ν•  수 있음

πŸ“Œ Serial / Concurrent

SerialConcurrent
μŠ€λ ˆλ“œ μˆ˜λ‹¨μΌ μŠ€λ ˆλ“œλ‹€μ€‘ μŠ€λ ˆλ“œ
attributesdefault.concurrent

πŸ“Œ sync / async

syncasync
동기비동기

πŸ“Œ main

  • μ „μ—­μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” Serial DispatchQueue
  • 일반적인 Serialνμ™€λŠ” 달리 앱이 μ‹€ν–‰λ˜λŠ” λ™μ•ˆμ—λŠ” 늘 λ©”λͺ¨λ¦¬μ— μ˜¬λΌμ™€ 있음
  • main에 μž‘μ—…μ„ μΆ”κ°€ν•˜λ©΄ Serial큐인 mainμŠ€λ ˆλ“œμ—μ„œ μž‘μ—…μ„ 처리
  • 이미 λ§Œλ“€μ–΄μ ΈμžˆλŠ” 큐

    Main Thread

    • μ•±μ˜ 생λͺ…주기와 같은 생λͺ…μ£ΌκΈ°λ₯Ό 가짐
    • μ•±μ˜ 기본이 λ˜λŠ” μŠ€λ ˆλ“œ
    • λ©”λͺ¨λ¦¬μ— 항상 μ˜¬λΌμ™€ μžˆλŠ” DefaultμŠ€λ ˆλ“œ
    • λ™μ‹œμ„± ν”„λ‘œκ·Έλž˜λ°μ—μ„œ 메인 μŠ€λ ˆλ“œμ—μ„œλΆ€ν„° ν•„μš”ν•œ 만큼의 μŠ€λ ˆλ“œκ°€ νŒŒμƒλ¨
    • globalμŠ€λ ˆλ“œλ“€κ³ΌλŠ” λ‹€λ₯΄κ²Œ Run Loopκ°€ μžλ™μœΌλ‘œ μ„€μ •λ˜κ³  μ‹€ν–‰
    • 메인 μŠ€λ ˆλ“œμ—μ„œ λ™μž‘ν•˜λŠ” Run Loopλ₯Ό Main Run Loop라고 함
    • UIμž‘μ—…μ€ 메인 μŠ€λ ˆλ“œμ—μ„œλ§Œ μž‘μ—…ν•  수 있음
DispatchQueue(label: "Serial")
DispatchQueue.main
  • main.sync : deadlock(κ΅μ°©μƒνƒœ)에 λΉ μ§€κ²Œ 됨, mainμŠ€λ ˆλ“œμ˜ Block-wait이 λλ‚˜κΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ” μƒνƒœκ°€ 됨, global().async{}둜 κ°μ‹Έμ„œ DispatchQueue에 λ˜μ§€λŠ” 것은 κ°€λŠ₯
  • main.async : DispatchQueue에 일단 μž‘μ—…μ„ addν•œ λ’€, mainμŠ€λ ˆλ“œκ°€ λͺ¨λ‘ 싀행이 된 λ’€ μž‘μ—…, μž‘μ—…μ΄ λλ‚˜κΈ°λ₯Ό 기닀리지 μ•ŠμŒ

πŸ“Œ global()

  • Concurrent Queue
  • global에 μž‘μ—…μ„ μΆ”κ°€ν•˜λ©΄ μƒˆλ‘œμš΄ μŠ€λ ˆλ“œλ₯Ό λ§Œλ“€μ–΄ κ·Έ μœ„μ—μ„œ μž‘μ—…μ„ 처리
  • λ©”λͺ¨λ¦¬μ— μ˜¬λΌμ™”λ‹€κ°€, μž‘μ—…μ΄ λλ‚˜κ³  λ‚˜λ©΄ λ©”λͺ¨λ¦¬μ—μ„œ 제거
  • 이미 λ§Œλ“€μ–΄μ ΈμžˆλŠ” 큐
DispatchQueue(label: "Concurrent", attributes: .concurrent)
DispatchQueue.global()
  • global().sync {} : mainμŠ€λ ˆλ“œ 말고 μƒˆλ‘œμš΄ globalμŠ€λ ˆλ“œλ₯Ό λ§Œλ“€μ–΄μ„œ μž‘μ—…μ„ 처리, μž‘μ—…μ΄ 끝날 λ•ŒκΉŒμ§€ 기닀렀야함(main Treadκ°€ λ©ˆμΆ°μ„œ κΈ°λ‹€λ¦Ό)
  • global().async {} : mainμŠ€λ ˆλ“œ 말고 μƒˆλ‘œμš΄ globalμŠ€λ ˆλ“œλ₯Ό λ§Œλ“€μ–΄μ„œ μž‘μ—…μ„ μ²˜λ¦¬ν• κ±΄λ°, λ‹€μŒ μž‘μ—…μ΄ μžˆλ‹€λ©΄ 기닀리지 μ•Šκ³  μ²˜λ¦¬ν•¨

πŸ“Œ DispatchWorkItem

  • μ½”λ“œ 블둝을 μΊ‘μŠν™”ν•¨
  • sync와 asyncλ©”μ„œλ“œμ˜ execute νŒŒλΌλ―Έν„°λ₯Ό 톡해 μ „λ‹¬ν•˜λ©΄ 됨
DispatchQueue.main.async(execute: task)
DispatchQueue.global().sync(excute: task)

πŸ“Œ asyncAfter

  • asyncλ©”μ„œλ“œλ₯Ό μ›ν•˜λŠ” μ‹œκ°„μ— ν˜ΈμΆœν•΄μ€„ 수 μžˆλŠ” λ©”μ„œλ“œ
  • prameter
    • deadline : μŠ€ν†±μ›ŒμΉ˜λ‘œ μΈ‘μ •ν•˜λ“―μ΄ 카운트
    • wallDeadline : μ‹œμŠ€ν…œ(κΈ°κΈ°)의 μ‹œκ°„μ„ κΈ°μ€€μœΌλ‘œ 카운트
  • μ•„λž˜λŠ” μ§€κΈˆ.now()μœΌλ‘œλΆ€ν„° 5초 ν›„ taskλ₯Ό μ‹€ν–‰μ‹œν‚¨λ‹€λŠ” μ˜ˆμ‹œ μ½”λ“œ
DispatchQueue.global().asyncAfter(deadline: .now() + 5, execute: task)
DispatchQueue.global().asyncAfter(wallDeadline: .now() + 5, excute: task)

πŸ“Œ asyncAndWait

  • 비동기 μž‘μ—…μ΄ λλ‚˜λŠ” μ‹œμ μ„ 기닀릴 수 있음
  • λ™μž‘ν•˜λŠ” λ…Όλ¦¬λŠ” sync와 μœ μ‚¬
DispatchQueue.global().asyncAndWait(execute: task)

πŸ“Œ Custom DispatchQueue

convenience init(label: String,
                 qos: DispatchQoS = .unspecified,
                 attributes: DispatchQueue.Attributes = [],
                 autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit,
                 target: DispatchQueue? = nil)

1️⃣ label

let myDispatchQueue = DispatchQueue(label: "testQueue")
  • DispatchQueue의 label을 μ„€μ •ν•΄μ£ΌλŠ” νŒŒλΌλ―Έν„°
  • 디버깅 ν™˜κ²½μ—μ„œ μΆ”μ ν•˜κΈ° μœ„ν•΄μ„œ μž‘μ„±ν•˜λŠ” Stringκ°’

2️⃣ qos

  • DispatchQoSνƒ€μž…μ˜ 값을 λ°›λŠ” νŒŒλΌλ―Έν„°
  • μ‹€ν–‰ 될 Taskλ“€μ˜ μš°μ„  μˆœμœ„λ₯Ό μ •ν•΄μ£ΌλŠ” κ°’

3️⃣ attributes

  • DispatchQueue의 속성을 μ •ν•΄μ£ΌλŠ” κ°’
  • .concurrent둜 μ΄ˆκΈ°ν™”ν•œλ‹€λ©΄ 닀쀑 μŠ€λ ˆλ“œ ν™˜κ²½
  • .initiallyInactive둜 μ΄ˆκΈ°ν™”ν•œλ‹€λ©΄ μž‘μ—… μ œμ–΄κ°€ κ°€λŠ₯, active()λ₯Ό ν˜ΈμΆœν•˜κΈ° μ „κΉŒμ§€λŠ” μž‘μ—…μ„ μ²˜λ¦¬ν•˜μ§€ μ•ŠμŒ
  • μ•„λž˜λŠ” .initiallyInactiveλ₯Ό μ‚¬μš©ν•œ μ½”λ“œ μ˜ˆμ‹œ
let myDispatch = DispatchQueue(label: "testQueue", attributes: .initiallyInactive)

myDispatch.async(execute: task) // μ½”λ“œ 블둝 호좜 μ•ˆλ¨.
myDispatch.activate()

4️⃣ autoreleaseFrequency

  • DispatchQueueκ°€ μžλ™μœΌλ‘œ 객체λ₯Ό ν•΄μ œν•˜λŠ” λΉˆλ„μ˜ 값을 κ²°μ •ν•˜λŠ” νŒŒλΌλ―Έν„°
  • autorealeaseν•΄μ£ΌλŠ” λΉˆλ„
  • defalutλŠ” inherit
    – inherit : targetκ³Ό 같은 λΉˆλ„λ₯Ό 가짐
    – workItem: workItem이 싀행될 λ•Œλ§ˆλ‹€ 객체듀을 ν•΄μ œ
    – never: autoreleaseλ₯Ό ν•˜μ§€ μ•ŠμŒ

μΆœμ²˜πŸ“š

πŸ»μ•Όκ³° λ‹·λ„·: GCD κΈ°λ³Έ

0개의 λŒ“κΈ€