ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

Day 2) ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์™€ ๋Ÿฐ๋ฃจํ”„

  • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ์ฑ…์ž„: ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ๋ ˆ์ด์•„์›ƒ/๋ Œ๋”๋ง ์ค€๋น„, UI ์—…๋ฐ์ดํŠธ
  • RunLoop: ์ž…๋ ฅ ์ด๋ฒคํŠธ/ํƒ€์ด๋จธ/์†Œ์Šค ์ฒ˜๋ฆฌ์˜ ๋ฐ˜๋ณต ๊ตฌ์กฐ
  • ๋™๊ธฐ ์ž‘์—…์ด UI๋ฅผ ๋ฉˆ์ถ”๊ฒŒ ํ•˜๋Š” ์ด์œ : ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฃจํ”„๋ฅผ ๋ชป ๋Œ์•„ ์ž…๋ ฅ/๊ทธ๋ฆฌ๊ธฐ ์ฒ˜๋ฆฌ ์ง€์—ฐ

์ •๋ฆฌ ์งˆ๋ฌธ

  • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ํ•˜๋ฉด ์•ˆ ๋˜๋Š” ์ž‘์—…์€ ๋ฌด์—‡์ด๋ฉฐ, ์–ด๋””๋กœ ๋ณด๋‚ด์•ผ ํ•˜๋Š”๊ฐ€?

Thread

์Šค๋ ˆ๋“œ(Thread)๋Š” “์ฝ”๋“œ”๊ฐ€ ์•„๋‹ˆ๋ผ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์‹คํ–‰ ํ๋ฆ„(์‹คํ–‰ ์ปจํ…์ŠคํŠธ)์— ๊ฐ€๊น๋‹ค.
OS๋Š” ํ”„๋กœ์„ธ์Šค ์•ˆ์— ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , ์Šค๋ ˆ๋“œ ๋‹จ์œ„๋กœ CPU ์‹œ๊ฐ„์„ ๋ฐฐ๋ถ„ํ•œ๋‹ค.

  • ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€์ง„ ๊ฒƒ(๊ฐ๊ฐ์ ์œผ๋กœ)
    • ํ˜ธ์ถœ ์Šคํƒ(Stack)
    • ๋ ˆ์ง€์Šคํ„ฐ ์ƒํƒœ(PC, SP ๋“ฑ)
    • ์Šค์ผ€์ค„๋ง ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ

Main Thread

๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋Š” iOS์—์„œ “UI ๋ฐ˜์‘์„ฑ”์„ ์ฑ…์ž„์ง€๋Š” ํ•ต์‹ฌ ์Šค๋ ˆ๋“œ๋‹ค.

  • ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ: ํ„ฐ์น˜/์ œ์Šค์ฒ˜/์Šคํฌ๋กค
  • UI ์—…๋ฐ์ดํŠธ: ์ƒํƒœ ๋ณ€๊ฒฝ ๋ฐ˜์˜
  • ๋ ˆ์ด์•„์›ƒ/๋ Œ๋”๋ง ์ค€๋น„: ๋‹ค์Œ ํ”„๋ ˆ์ž„์— ๋ฐ˜์˜๋  ๋ณ€๊ฒฝ์„ ์ •๋ฆฌํ•˜๊ณ  ์ œ์ถœ(์ปค๋ฐ‹) ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋กœ ๋งŒ๋“ค๊ธฐ

์‚ฌ์šฉ์ž๋Š” CPU๋‚˜ OS๋ฅผ ์ง์ ‘ ๋ณด์ง€ ๋ชปํ•˜๊ณ  ํ™”๋ฉด์˜ ๋ฐ˜์‘๋งŒ ๋ณธ๋‹ค.

๊ทธ๋ž˜์„œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ง‰ํžˆ๋ฉด ์‚ฌ์šฉ์ž๋Š” ๊ณง๋ฐ”๋กœ “์•ฑ์ด ๋ฉˆ์ท„๋‹ค”๋กœ ์ฒด๊ฐํ•œ๋‹ค.


RunLoop

RunLoop๋Š” ์Šค๋ ˆ๋“œ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ˜๋ณต ๊ตฌ์กฐ๋‹ค.

  • ํ•  ์ผ ์žˆ์œผ๋ฉด ๊นจ์–ด์„œ ์ฒ˜๋ฆฌ
  • ํ•  ์ผ ์—†์œผ๋ฉด ์ž ๋“ค์–ด(sleep) CPU๋ฅผ ์‰ฌ๊ฒŒ ํ•จ

๋น„์œ 

  • Main Thread = ๊ฒฝ๋น„ ์•„์ €์”จ (์‹ค์ œ๋กœ ์ผํ•˜๋Š” ์ฃผ์ฒด)
  • RunLoop = ๊ฒฝ๋น„ ์•„์ €์”จ์˜ ์—…๋ฌด ๋ฃจํ‹ด(์ผ๊ณผํ‘œ)

๊ฒฝ๋น„ ์•„์ €์”จ๋Š” ์•„๋ž˜๋ฅผ ๋ฐ˜๋ณตํ•œ๋‹ค.

  • ํ•  ์ผ ์—†์œผ๋ฉด ์˜์ž์—์„œ ์ž ๋“ ๋‹ค
  • ์ดˆ์ธ์ข…์ด ์šธ๋ฆฌ๋ฉด(์ด๋ฒคํŠธ/์†Œ์Šค) ๊นฌ๋‹ค
  • ์•Œ๋žŒ์‹œ๊ณ„๊ฐ€ ์šธ๋ฆฌ๋ฉด(ํƒ€์ด๋จธ) ๊นฌ๋‹ค

 

Main vs Background

  • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ RunLoop๋Š” ์‹œ์Šคํ…œ/ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ž๋™์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•œ๋‹ค.
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋Š” ํ•„์š”ํ•  ๋•Œ๋งŒ RunLoop๋ฅผ ์ง์ ‘ ๋Œ๋ฆฐ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด, ํฌํŠธ ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง€(Port-based input source)๋ฅผ ๋ฐ›์•„์•ผ ํ•ด์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์† ์‚ด์•„ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋ฉด,

    ๊ทธ ์Šค๋ ˆ๋“œ์— RunLoop๋ฅผ ๋ถ™์—ฌ์„œ ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋งŒ๋“ ๋‹ค.
(+) RunLoop์—์„œ ์‹คํ–‰๋œ๋‹ค๋Š” ๋ง
RunLoop๋Š” ๋ณ„๋„์˜ ์—”์ง„์ด ์•„๋‹ˆ๋ผ, ๊ทธ ์Šค๋ ˆ๋“œ(๋Œ€๋ถ€๋ถ„ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ)๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ˜๋ณต ๋ฃจํ‹ด์ด๋‹ค.
๊ทธ๋ž˜์„œ “RunLoop์—์„œ ์‹คํ–‰๋œ๋‹ค”๋Š” ๋ง์€ ๋ณดํ†ต “๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ RunLoop ํ„ด ์ค‘์— ๊ทธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค”๋Š” ๋œป์ด๋‹ค.


RunLoop ์ •๋ฆฌ (Deep Dive)

- Timer

ํƒ€์ด๋จธ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด “1์ดˆ๋งˆ๋‹ค ์ด๋ฒคํŠธ๊ฐ€ ํ์— ์Œ“์ธ๋‹ค”๊ธฐ๋ณด๋‹ค๋Š”,

  • RunLoop๊ฐ€ ๋‹ค์Œ์— ๊นจ์–ด๋‚˜์•ผ ํ•  ์‹œ๊ฐ(next fire time)์„ ๊ณ„์‚ฐํ•ด๋‘๊ณ 
  • ๊ทธ ์‹œ๊ฐ๊นŒ์ง€๋Š” ๋ณดํ†ต ์ž ๋“  ๋’ค
  • ์‹œ๊ฐ„์ด ๋˜๋ฉด ๊นจ์–ด๋‚˜ “์ง€๊ธˆ ์‹คํ–‰ํ•  ํƒ€์ด๋จธ๊ฐ€ ์žˆ๋‚˜?”๋ฅผ ํ™•์ธํ•˜๊ณ  fire ํ•œ๋‹ค

- Source

RunLoop๋ฅผ ๊นจ์šฐ๋Š” ๊ฑด ํƒ€์ด๋จธ๋งŒ์ด ์•„๋‹ˆ๋‹ค.

  • ์ž…๋ ฅ ์ด๋ฒคํŠธ(ํ„ฐ์น˜/์ œ์Šค์ฒ˜)
  • ๋ฉ”์ธ ํ ์ž‘์—…(DispatchQueue.main)
  • ํฌํŠธ ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง€(Mach port, socket ๋“ฑ)

์ฆ‰, RunLoop๋Š” ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜(์•Œ๋žŒ) / ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜(์ดˆ์ธ์ข…) ๋‘ ์ถ•์œผ๋กœ ๊นจ์–ด๋‚œ๋‹ค๊ณ  ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ์‰ฝ๋‹ค.

Port-based / Custom Source (์•„์ฃผ ์‰ฝ๊ฒŒ)

  • Port-based source: “์ „ํ™”์„ /์ดˆ์ธ์ข…” ๊ฐ™์€ ํ†ต๋กœ๋กœ ๋ฉ”์‹œ์ง€๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊นจ์„œ ์ฒ˜๋ฆฌ
  • Custom source: ๋‚ด๊ฐ€ ์ง์ ‘ ๋งŒ๋“  ๊ทœ๊ฒฉ(์ฝœ๋ฐฑ)์œผ๋กœ ๊นจ์šฐ๋Š” ์‚ฌ์šฉ์ž ์†Œ์Šค

Run Loops— Threading Programming Guide (Apple Archive)

RunLoop (Foundation)

CFRunLoop.c (CoreFoundation ์˜คํ”ˆ์†Œ์Šค)


RunLoopTracer (Self Check)

RunLoop๊ฐ€ “์‹ค์ œ๋กœ ์ž ๋“ค์—ˆ๋‹ค๊ฐ€ ๊นจ๋Š”์ง€” ํ™•์ธํ•˜๋ ค๊ณ , ๋ฉ”์ธ RunLoop์— Observer๋ฅผ ๋ถ™์—ฌ activity๋ฅผ ์ฐ์–ด๋ดค๋‹ค.

์ฝ”๋“œ(ํ•ต์‹ฌ)

final class RunLoopTracer {
    private var observer: CFRunLoopObserver?

    func start() {
        stop()

        let activities: CFRunLoopActivity = [
            .entry,
            .beforeTimers,
            .beforeSources,
            .beforeWaiting,
            .afterWaiting,
            .exit
        ]

        observer = CFRunLoopObserverCreateWithHandler(
            kCFAllocatorDefault,
            activities.rawValue,
            true,
            0
        ) { _, activity in
            switch activity {
            case .beforeTimers:  print("RunLoop: beforeTimers")
            case .beforeSources: print("RunLoop: beforeSources")
            case .beforeWaiting: print("RunLoop: beforeWaiting (going to sleep)")
            case .afterWaiting:  print("RunLoop: afterWaiting (woke up)")
            default: break
            }
        }

        if let observer {
            CFRunLoopAddObserver(CFRunLoopGetMain(), observer, .commonModes)
        }
    }

    func stop() {
        if let observer {
            CFRunLoopRemoveObserver(CFRunLoopGetMain(), observer, .commonModes)
        }
        observer = nil
    }
}

๋กœ๊ทธ(์š”์•ฝ)

RunLoop: beforeTimers
RunLoop: beforeSources
RunLoop: beforeWaiting (going to sleep)
RunLoop: afterWaiting (woke up)
...

์—ฌ๊ธฐ์„œ ์ธ์ƒ์ ์ด์—ˆ๋˜ ๊ฑด ๋‘ ๊ฐ€์ง€๋‹ค.

  1. RunLoop๋Š” “๊ณ„์† ๋ฐ”์˜๊ฒŒ ๋„๋Š” while” ๋А๋‚Œ์ด ์•„๋‹ˆ๋ผ,
    ์ž ๋“ค๊ธฐ ์ง์ „(beforeWaiting)๊ณผ ๊นจ์–ด๋‚œ ์งํ›„(afterWaiting)๊ฐ€ ๋ฐ˜๋ณต๋˜๋Š”, ์ง„์งœ “sleep ↔ wake” ๊ตฌ์กฐ๋กœ ๋ณด์˜€๋‹ค.
  2. ๋‚ด๊ฐ€ ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ๋„ afterWaiting์ด ์ฐํ˜”๋Š”๋ฐ, ์ด๊ฑด ์ •์ƒ์ด๋‹ค.
    ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด ์—†์–ด๋„ ์‹œ์Šคํ…œ ๋‚ด๋ถ€ ์ž‘์—…/๋ฉ”์ธ ํ ์ž‘์—…/ํƒ€์ด๋จธ ๋“ฑ์œผ๋กœ RunLoop๋Š” ๊นจ์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค.


Problem

์•ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ ํ™”๋ฉด์ด ๋ฒ„๋ฒ…์ด๊ฑฐ๋‚˜ ๋ฉˆ์ถ”๋Š” ํ˜„์ƒ์„ ํ•œ ๋ฒˆ์ฏค์€ ๊ฒฝํ—˜ํ•ด๋ดค์„ ๊ฒƒ์ด๋‹ค. ๋Œ€๋ถ€๋ถ„์€ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฒด๊ฐ๋œ๋‹ค.

  • ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €๋Š”๋ฐ ๋ฐ˜์‘์ด ๋Šฆ๋‹ค
  • ์Šคํฌ๋กค์ด ํˆญ ๋Š๊ธด๋‹ค
  • ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ฉˆ์ถ˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค

์ด ํ˜„์ƒ๋“ค์„ RunLoop ๊ด€์ ์—์„œ ํ•œ ๋ฌธ์žฅ์œผ๋กœ ๋ฐ”๊พธ๋ฉด ์ด๋ ‡๊ฒŒ ๋œ๋‹ค.

๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™๊ธฐ ์ž‘์—…์— ๋ฌถ์—ฌ RunLoop ํ„ด์ด ์ง„ํ–‰๋˜์ง€ ๋ชปํ–ˆ๋‹ค.


์›์ธ 

๋Œ€ํ‘œ์ ์ธ ์ผ€์ด์Šค๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์ •๋ฆฌ๋œ๋‹ค.

  1. ๊ธด CPU ์ž‘์—…
    - ๋Œ€์šฉ๋Ÿ‰ JSON ๋””์ฝ”๋”ฉ, ์ด๋ฏธ์ง€ ๋””์ฝ”๋”ฉ/๋ฆฌ์‚ฌ์ด์ฆˆ, ๋ณต์žก ๊ณ„์‚ฐ, ํฐ ๋ ˆ์ด์•„์›ƒ ์ž‘์—…
  2. I/O ๋ธ”๋กœํ‚น
    - ํŒŒ์ผ/DB/๋„คํŠธ์›Œํฌ ๊ฐ™์€ “๊ธฐ๋‹ค๋ฆผ์ด ๋ณธ์งˆ”์ธ ์ž‘์—…์„ UI ํ๋ฆ„์—์„œ ๋™๊ธฐ๋กœ ์ˆ˜ํ–‰
  3. ๋™๊ธฐํ™” ๋Œ€๊ธฐ
    - ๋ฝ ๊ฒฝํ•ฉ, ์„ธ๋งˆํฌ์–ด๋กœ ๋ฉ”์ธ์ด ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ตฌ์กฐ
    - “๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ ๋๋‚  ๋•Œ๊นŒ์ง€ ๋ฉ”์ธ์ด ๋ฉˆ์ถ˜๋‹ค”๊ฐ€ ๊ทธ๋Œ€๋กœ UI ๋ฉˆ์ถค์œผ๋กœ ์ด์–ด์ง

ํ•ด๊ฒฐ

๊ฒฐ๋ก ์€ ๋‹จ์ˆœํ•˜์ง€๋งŒ, ์ด ๋‹จ์ˆœํ•จ์„ ์ง€ํ‚ค๋Š” ๊ฒŒ ์–ด๋ ต๋‹ค.

  • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—๋Š” UI ๊ด€๋ จ๋งŒ ๋‚จ๊ธด๋‹ค.
  • ๋ฌด๊ฑฐ์šด ์ž‘์—…์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ๋ณด๋‚ด๊ณ , ๊ฒฐ๊ณผ๋งŒ ๋ฉ”์ธ์œผ๋กœ ๋ณต๊ท€ํ•ด UI์— ๋ฐ˜์˜ํ•œ๋‹ค.

๋‹ค๋งŒ “๋ฌด์กฐ๊ฑด ๋ฐฑ๊ทธ๋ผ์šด๋“œ”๊ฐ€ ์ •๋‹ต์€ ์•„๋‹ˆ๋‹ค.
์ž‘์—…์„ ๋ถ„๋ฆฌํ•˜๋ฉด ์Šค์ผ€์ค„๋ง/ํ์ž‰/๋ฉ”์ธ ๋ณต๊ท€/๋™๊ธฐํ™” ๋น„์šฉ์ด ์ƒ๊ธฐ๊ณ , ์ž‘์—…์ด ์ž‘๋‹ค๋ฉด ์˜คํžˆ๋ ค ๊ทธ ๋น„์šฉ์ด ๋” ํด ์ˆ˜ ์žˆ๋‹ค.

 

๊ทธ๋ž˜๋„ I/O, ๋””์ฝ”๋”ฉ, ํฐ ์—ฐ์‚ฐ์ฒ˜๋Ÿผ ์‹คํ–‰ ์‹œ๊ฐ„์ด ํ”๋“ค๋ฆฌ๋Š” ์ž‘์—…์€ ์ตœ์•… ์ผ€์ด์Šค์—์„œ

๋ฉ”์ธ RunLoop๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„๋ฆฌํ•˜๋Š” ํŽธ์ด ์•ˆ์ „ํ•˜๋‹ค.

 

์˜ˆ)

  • CPU/IO ์ž‘์—… → ๋ฐฑ๊ทธ๋ผ์šด๋“œ
  • UI ์—…๋ฐ์ดํŠธ → MainActor / DispatchQueue.main


(+) UI  Update (Commit๊ณผ Frame)

UI ๊ฐฑ์‹ ์„ ์ดํ•ดํ•  ๋•Œ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋Š” ์ด๊ฑฐ๋‹ค.

๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋Š” “ํ”ฝ์…€์„ ์ง์ ‘ ๊ทธ๋ฆฐ๋‹ค”๊ธฐ๋ณด๋‹ค๋Š”,
๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋ชจ์•„ ์ปค๋ฐ‹(์ œ์ถœ)ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค๊ณ , ์ œ๋•Œ ์ œ์ถœ๋˜๊ฒŒ ํ•˜๋Š” ์ชฝ์— ๊ฐ€๊น๋‹ค.

 

CATransaction

๋ณ€๊ฒฝ์‚ฌํ•ญ์„ “๋ฌถ๋Š” ๋‹จ์œ„”๋กœ ์ดํ•ดํ•˜๋ฉด ํŽธํ•˜๋‹ค.

  • ๋น„์œ : ์žฅ๋ฐ”๊ตฌ๋‹ˆ/์„œ๋ฅ˜ ๋ฌถ์Œ
  • ์ด ๋ณ€๊ฒฝ๋„, ์ € ๋ณ€๊ฒฝ๋„ ๋ชจ์•„์„œ ํ•œ ๋ฒˆ์— ์ œ์ถœ

CADisplayLink

๋””์Šคํ”Œ๋ ˆ์ด ๋ฆฌํ”„๋ ˆ์‹œ์— ๋งž์ถฐ ์ฝœ๋ฐฑ์„ ๋ฐ›๋Š” “ํ”„๋ ˆ์ž„ ๋ฐ•์ž ์†Œ์Šค”๋‹ค.

  • ๋น„์œ : ๋ฉ”ํŠธ๋กœ๋†ˆ
  • “์ง€๊ธˆ ํ”„๋ ˆ์ž„ ํƒ€์ด๋ฐ์ด์•ผ”๋ฅผ ์•Œ๋ ค์คŒ

Explore UI animation hitches and the render loop

Understanding hitches in your app


์ •๋ฆฌ ์งˆ๋ฌธ

- ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ํ•˜๋ฉด ์•ˆ ๋˜๋Š” ์ž‘์—…์€ ๋ฌด์—‡์ธ๊ฐ€?

  • ๋Œ€์šฉ๋Ÿ‰ ๋””์ฝ”๋”ฉ/ํŒŒ์‹ฑ, ์ด๋ฏธ์ง€ ๋””์ฝ”๋”ฉ/๋ฆฌ์‚ฌ์ด์ฆˆ ๊ฐ™์€ ๋ฌด๊ฑฐ์šด CPU ์ž‘์—…
  • ํŒŒ์ผ/DB/๋„คํŠธ์›Œํฌ ๊ฐ™์€ ๋ธ”๋กœํ‚น I/O
  • ๋ฝ/์„ธ๋งˆํฌ์–ด ๋“ฑ์œผ๋กœ ๋ฉ”์ธ์ด “๊ธฐ๋‹ค๋ฆฌ๋Š”” ๊ตฌ์กฐ

- ์–ด๋””๋กœ ๋ณด๋‚ด์•ผ ํ•˜๋Š”๊ฐ€?

  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ(Concurrency/GCD/OperationQueue)๋กœ ๋ณด๋‚ด๊ณ 
  • UI ๋ฐ˜์˜๋งŒ ๋ฉ”์ธ์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค

๊ฒฐ๋ก 

  • RunLoop๋Š” “๊ณ„์† ๋„๋Š” while”์ด ์•„๋‹ˆ๋ผ, ๋Œ€๋ถ€๋ถ„ ์ž ๋“ค์–ด ์žˆ๋‹ค๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๊นจ์–ด๋‚˜๋Š” ๊ตฌ์กฐ๋กœ ๋ณด๋Š” ๊ฒŒ ์ดํ•ด๊ฐ€ ์‰ฝ๋‹ค.
  • UI๊ฐ€ ๋ฉˆ์ถ˜๋‹ค๋Š” ๊ฑด ๋Œ€๊ฐœ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™๊ธฐ ์ž‘์—…์— ๋ฌถ์—ฌ RunLoop ํ„ด์ด ๋ฐ€๋ฆฐ ๊ฒฐ๊ณผ๋‹ค.
  • ๊ทธ๋ž˜์„œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋Š” ๊ฒฐ๊ตญ,
    “๋ฉ”์ธ์„ ๊ฐ€๋ณ๊ฒŒ ์œ ์ง€ํ•˜๊ณ , ๋ฌด๊ฑฐ์šด ์ž‘์—…์€ ๋ถ„๋ฆฌํ•˜๋Š” ์„ค๊ณ„”๋กœ ๊ท€๊ฒฐ๋œ๋‹ค.


์•„๋ž˜๋Š” ๋‚ด๊ฐ€ ํ•ด๋‹น ๋‚ด์šฉ์„ ํ•™์Šตํ•˜๊ธฐ ์œ„ํ•ด GPT์™€ ์—ด์‹ฌํžˆ ์”จ๋ฆ„ํ•œ ๋‚ด์šฉ์ด๋‹ค. 

Chat GPT