iOSμμ Concurrency(λμμ±) νλ‘κ·Έλλ°μ λν΄ μμ보μ.
- Concurrency(λμμ±) νλ‘κ·Έλλ°μ΄λ ?
- GCD/Operation?
- DispatchQueue μ μ’
λ₯
- Synchronous(λκΈ°) VS Asynchronous(λΉλκΈ°)
- Serial(μ§λ ¬) VS Concurrency(λμ)
π₯ Concurrency(λμμ±) νλ‘κ·Έλλ°μ΄λ ?
κ°μ μκ° λ΄μ λ€μμ μμ μ΄ μ€νλλ νλ‘κ·Έλλ°
ν μ°λ λ μμ λ§μ μμ Taskκ° μμ΄λ©΄μ μλ μ§μ°, μ±λ₯ μ ν λ± λ°μνλ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν λ°©λ²μΌλ‘
λ€λ₯Έ μ°λ λλ‘ λΆμ°μμΌμ λ¬Έμ λ₯Ό ν΄κ²°νλ€.
λ³΄ν΅ μ€λ λ μ²λ¦¬λ₯Ό νλ μμ λ€μ μκ°μ΄ κ½€λ 걸리λ ν° μμ μ΄κ±°λ μΈμ λλ μ§ λͺ¨λ₯΄λ μ μ μλ μμ μ μ¬μ©λλ€. μλ₯Ό λ€μ΄ λ€νΈμν¬, νμΌλ‘λ© λ±.
κ·Έλ λ€λ©΄, μμ μ μ΄λ»κ² λΆμ° μν¬ μ μμκΉ?
μμ μ μ΄λ»κ² λ€λ₯Έ μ°λ λμμ λμμ μΌμ νκ² ν μ μμκΉ?
iOSμ λμμ± νλ‘κ·Έλλ°μ λκΈ°νλ ¬(Queue)μ λ£κΈ°λ§ νλ©΄ μμμ OSκ° μμμ μ°λ λλ₯Ό μ°Ύμμ λΆμ°μ²λ¦¬(μ°λ λ κ΄λ¦¬)νλ€.
μ΄λ, μ μ μ μΆλ‘(FIFO)λ‘ λμ
λ°λΌμ, κ°λ°μκ° ν΄μΌν μΌμ Queueλ‘ Taskλ€μ 보λ΄λ κ²μ΄λ€.
π₯ GCD/Operation
μμμ λ§ν Queueλ‘ Taskλ€μ 보λ΄λ λ°©λ²μ΄λ€.
iOS κ°λ°μμ μ£Όλ‘ μ¬μ©λκ³ μλ λμμ± νλ‘κ·Έλλ° API 2κ°μ§λ‘ GCD, Operationκ° μλ€.
- μ§μ μ μΌλ‘ μ°λ λλ₯Ό κ΄λ¦¬νμ§ μκ³ , "ν(Queue, λκΈ°νλ ¬)"λΌλ κ°λ μ μ΄μ©ν΄ μμ μ λΆμ°μ²λ¦¬
μ¬κΈ°μ κ°λ¨νκ² λ³΄κ³ μΆν μμΈνκ² λ€λ£° μμ !
βοΈ GCD(Grand Central Dispatch)
- DispatchQueue μ¬μ©
- Low level API λ‘ μ€λ λ νμ κ΄λ¦¬νλ©° dispatch queueμ μλ μμ λ€μ μ¬μ©ν κ°λ₯ν μ€λ λμ μ€μΌμ₯΄λ§
- κ°λ°μλ μ€λ λ κ΄λ¦¬μ μ κ²½μ°μ§ μμλ λλ©° Taskλ€μ dispatch queueμ λ£μ΄μ£Όλ©΄ λ¨.
- κ°λ¨ν μΌ, ν¨μλ₯Ό μ¬μ©νλ μμ (λ©μλ μμ£Ό)μμ μ¬μ©
[μμ μ½λ]
// μλ μ½λμ μλ―Έ
//"νλ‘ λ³΄λΌκΊΌμΌ","νμμ’
λ₯","λΉλκΈ°μ μΌλ‘"
DispatchQueue.global().async {
//λ€λ₯Έ μ°λ λλ‘ λ³΄λΌ μμ
μ λ°°μΉ
//μ΄ ν΄λ‘μ νλκ° μμ
μ λν±μ΄
}
βοΈ Operation
- Operation Queue μ¬μ©
- GCDλ₯Ό κΈ°λ°μΌλ‘ μμ±λ¨
- Operation : GCD + μ¬λ¬κ°μ§ κΈ°λ₯(μμ μ·¨μ, μμμ§μ , μμ‘΄μ± λ±)
- 볡μ‘ν μΌ
- μ¬μ¬μ©μ± : λ°μ΄ν°μ κΈ°λ₯μ μΊ‘μνν κ°μ²΄
- μμ λ¨μ νΉμ μμ μ λννκ³ λμ€μ μ€νν μ μμΌλ©° ν΄λΉ μμ λ¨μλ₯Ό μ¬λ¬λ² μ μΆ κ°λ₯
π₯ Synchronous(λκΈ°) VS Asynchronous(λΉλκΈ°)
βοΈ Synchronous(λκΈ°)
- 첫λ²μ§Έ μμ μμ ν μμ μ΄ λλλ κ²μ κΈ°λ€λ¦° ν λ€μ μμ μ μ²λ¦¬νλ€.
- μ¦, μμ μ΄ λλκΈ° μ κΉμ§ λ©μΈμ°λ λ(Thread1)κ° λ€λ₯Έ μμ μ μννμ§ λͺ»νλ€.
- *λκΈ°μ μΌλ‘ 보λ΄λ μ½λλ₯Ό μ§λλΌλ μ€μ§μ μΌλ‘ λ©μΈμ°λ λμμ μμ°¨μ μΌλ‘ μ²λ¦¬ λ¨.(λκΈ°μ½λμ λμΌνκ² μμ )
[λκΈ° μ½λ]
DispatchQueue.main.sync {
// Main νμμ λκΈ° λ°©μμΌλ‘ μ€νν μ½λ
}
>> λ§μ΄ μ¬μ© μνλ€.
WHY ? μ²λ¦¬ μκ°μ μ€μ΄κΈ° μνμ¬ λΉλκΈ°λ₯Ό μ¬μ©(Queueλ₯Ό ν΅ν΄ μ°λ λ λΆμ°)νλκ±°λΌ λκΈ°λ κ±°μ μ¬μ© μν¨.
βοΈ Asynchronous(λΉλκΈ°)
- 첫λ²μ§Έ μμ μμ ν μμ μ΄ λλλ κ²μ κΈ°λ€λ¦¬μ§ μκ³ λ°λ‘ λ€μ μμ μ μ²λ¦¬νλ κ²
- λ©μΈμ°λ λ(Thread1)κ° λ€λ₯Έ μΌ μ²λ¦¬λ₯Ό μμν μ μλ€.
- μ¬λ¬κ°μ§ μμ μ 'λμμ' μ²λ¦¬ κ°λ₯!!
*"λΉλκΈ°" κ°λ μ΄ νμν μ΄μ λ
λλΆλΆ μλ²μμ ν΅μ (λ€νΈμν¬ μμ ) λλ¬Έ
λ€νΈμν¬μ κ΄λ ¨λ μμ λ€μ λ΄λΆμ μΌλ‘ λΉλκΈ°μ μΌλ‘ ꡬνλμ΄ μμ
[λΉλκΈ° μ½λ]
DispatchQueue.main.async {
// Main νμμ λΉλκΈ° λ°©μμΌλ‘ μ€νν μ½λ
// μ¦, μ€ννκ³ κΈ°λ€λ¦¬μ§ μλ μ½λ
}
[λκΈ°, λΉλκΈ° μμ μμ μ½λ λΉκ΅]
μλ μ½λμμ taskλ€μ λκΈ°, λΉλκΈ° μμ μ μννμ¬ μΆλ ₯ κ°μ λΉκ΅ν΄ 보μ.
func task1() {
print("Task 1 μμ")
sleep(1)
print("Task 1 μλ£β
")
}
func task2() {
print("Task 2 μμ")
print("Task 2 μλ£β
")
}
func task3() {
print("Task 3 μμ")
sleep(4)
print("Task 3 μλ£β
")
}
βοΈ μ μ½λλ₯Ό λκΈ°λ‘ μ€νν κ²½μ°
// λκΈ° μμ
queue.sync {
task1()
}
queue.sync {
task2()
}
queue.sync {
task3()
}
[μ€ν κ²°κ³Ό]
μλμ²λΌ μ½λκ° μμμ μΌλ‘ μμ λ, λκΈ° μμ κ³Ό λμΌν κ²°κ³Όλ₯Ό μ»λλ€.
task1()
task2()
task3()
Why?
iOSμμ Main Threadλ μ€μ§ νκ°λ§ μ‘΄μ¬νκ³ Main Queueμμ μ€νλλλ°,
μ΄ Main Queueλ Serial QueueλΌμ νλ²μ ν κ°μ Taskλ°μ μ€ννμ§ λͺ»νκΈ° λλ¬Έμ μμ°¨μ μΌλ‘ μ€νλ¨.
βοΈ μ μ½λλ₯Ό λΉλκΈ°λ‘ μ€νν κ²½μ°
// λΉλκΈ° μμ
queue.async {
task1()
}
queue.async {
task2()
}
queue.async {
task3()
}
[μ€ν κ²°κ³Ό]
π₯ Serial(μ§λ ¬) ν VS Concurrency(λμ) ν
νμ νΉμ±μ λ°λΌ ꡬλΆλ μ§λ ¬κ³Ό λμλ‘ λλμ΄μ§
βοΈ Main Queue - Serial(μ§λ ¬) ν
- Queueμμ λ°μ ν μ€ν¬λ€μ λ¨ νλμ λ€λ₯Έ μ°λ λλ‘ λ³΄λ΄λ ν
- >> ν λ²μ νλμ ν μ€ν¬λ₯Ό μ€ννμ¬ μμ°¨μ μΌλ‘ μ€ν
- μμκ° μ€μν μμ μ μ²λ¦¬ν λ μ¬μ©
- Main Threadμμ μ¬μ©λλ Queue(Main Queue)
βοΈ Global Queue - Concurrency(λμ) ν
- Queueμμ λ°μ ν μ€ν¬λ€μ μ¬λ¬κ°μ λ€λ₯Έ μ°λ λλ‘ λ³΄λ΄λ ν
- >> λ§μ μμ μ λμμ μ€ν
- κ°μ λ 립μ μ΄μ§λ§ μ μ¬ν μ¬λ¬κ°μ μμ μ μ²λ¦¬ν λ μ¬μ©
ex)
> μ λ³λ‘ μ μ¬ν μμ μ κ°κΈ° λ€λ₯Έ μλ²μμ μννλ μ²λ¦¬
- high, default, low, background λ€ κ°μ§ λ€λ₯Έ μ°μ μμλ₯Ό κ°μ§ μ μλ€.
- qos(quality of service) classμ νλ‘νΌν°λ₯Ό μ§μ νμ¬ μ¬μ©
let backgroundQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background)
*ν΄λΉ λ΄μ©μ μΈνλ° κ°μ λ³΄κ³ μ 리ν λ΄μ©μ λλ€.