์ด์ ๊ธ์์ ๋์์ฑ์ ๋ํด์ ์์๋ณด์๋ค. ํ์ง๋ง iOS์์๋ Thread๋ฅผ ์ง์ ์์ฑํด์ ์์ ํ์ง ์๋๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์ ๊ฐ๋ฅํ๊ฒ ํ ๊น? ๊ทธ ๋ต์ธ GCD์ ๋ํด์ ์์๋ณด์. ์์ํด๋ณด์.
ํด๋น ๊ธ์ ์ฌ๋ด ๋ฐํ์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑํ์์ต๋๋ค.
Grand Central Dispatch(CGD)
Apple์ด ๊ฐ๋ฐํ ๊ธฐ์ ๋ก, ๋ฉํฐ ์ฝ์ด ํ๋ก์ธ์ค ํ๊ฒฝ์์์ ์ ํ๋ฆฌ์ผ์ด์ ์ง์์ ์ต์ ํํ๊ธฐ ์ํด์ ๊ฐ๋ฐ๋์๋ค.
- low level C based API
- ์ค๋ ๋ ๊ด๋ฆฌ์ ์ฑ ์์ ์์คํ ์ผ๋ก ์ด๋
- ์์คํ ์ด ํ์ํ ์์คํ ์ ๋ง๋ค๊ณ , ํด๋น ์ค๋ ๋์์ ์คํ๋๋๋ก ์์ ์ ์์ฝํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉ๋๋ค.
์ฌ๊ธฐ์ ์์คํ ์ด ๊ด๋ฆฌํ๋ Queue๊ฐ ์๋๋ฐ, ์ด๊ฑธ Dispatch Queue๋ผ ํ๋ค. ์ด Queue์ ํ๊ณ ์ถ์ ์์ ์ ์ ์ํด์ ์ฌ๊ธฐ์ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
Dispatch Queue
- ํ์ ์์
์ ์ ์ถํ๋ ๊ตฌ์กฐ
- FIFO ๊ตฌ์กฐ, ์ถ๊ฐ๋ ์์๋๋ก ์์ ์ด ์์๋จ
- ์์ ์ ํจ์ ๋๋ Block(clousure in swift)๋ก ํํํ๋ค.
- Dispatch Queue์ ์ ์ถ๋ ์์ ์ ์์คํ ์์ ๊ด๋ฆฌํ๋ ์ค๋ ๋ ํ์์ ์คํ๋๋ค.
- ์์
์ ์์ฐจ์ ์ผ๋ก ๋๋ ๋์์ ์คํ์ด ๊ฐ๋ฅํ๋ค
- ์ด ๋ถ๋ถ์ ์์ ๋ฉด์ ๊ด ์์์์, ์ค ์์ฒด๋ฅผ ํ๊ฐ๋ก๋ง ์ธ์ธ ๊ฒ์ธ์ง, ์ฌ๋ฌ์ค๋ก ์ธ์ธ ๊ฒ์ธ์ง์ ๋์๋๋ ๋ถ๋ถ์ด๋ค.
- Serial
- ์์ ์ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ถ์ ๊ฒฝ์ฐ
- Concurrent Dispatch Queue
- ๋์์ ์คํํ๊ณ ์ถ์ ๊ฒฝ์ฐ
- ์์
์ ๋๊ธฐ์ ์ผ๋ก ํน์ ๋น๋๊ธฐ์ ์ผ๋ก ์ค์ผ์ฅด๋งํ ์ ์๋ค.
- ๋๊ธฐ์ ์ผ๋ก ์ค์ผ์ฅด๋ง ํ ๊ฒฝ์ฐ, ํด๋น ์์ ์ด ์คํ์ ๋ง์น ๋๊ฐ์ง ์ฝ๋๋๊ธฐ
- ๋น๋๊ธฐ์ ์ผ๋ก ์ค์ผ์ฅด๋ง ํ ๊ฒฝ์ฐ, ํด๋น ์์ ์ด ์คํ ์ค์๋ ์ฝ๋ ์คํ
Serial Dispatch Queue
- ํ์ ์์ ์ด ์ถ๊ฐ๋ ์์๋ก ํ ๋ฒ์ ํ๋์ ์์ ๋ง ์คํ
- ์ด์ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ์ ์์ ์ ์์ํ์ง ์๊ณ ๋๊ธฐ
- ๋ง์ฝ ๋ ๊ฐ ์ด์์ Serial Queue๊ฐ ์๋ค๋ฉด, ์ต๋ 2๊ฐ์ ์์
์ ๋์์ ์คํํ ์๋ ์์
- ๋ฌผ๋ฆฌ์ ์๋ฏธ
- ํ๋์จ์ด ์ฝ์ด์์ ๋ฐ๋ผ ๋ณ๋ ฌ ์ํ ์ ํ์ด ์์ ์ ์์
์์ฑ ๋ฐฉ๋ฒ์ผ๋ก๋ 2๊ฐ๊ฐ ์๋ค. ๋ฐ๋ก main queue๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, custom queue๋ฅผ ์ฌ์ฉํ๊ฑฐ๋.
- Main Queue
DispatchQueue.main
- Custom Queue
DispatchQueue(label: "customSerial")
์ฌ๊ธฐ์ ํด๋น Queue๋ฅผ ๋๊ธฐ์ ์ผ๋ก, ๋น๋๊ธฐ์ ์ผ๋ก ์ํํ๋๋ก ์ต์ ์ ๊ฑธ ์ ์๋ค.
Serial Sync Dispatch Queue
let queue = DispatchQueue(label: "SerialSyncQueue")
queue.sync {
print("task 1")
}
queue.sync {
print("task 2")
}
queue.sync {
print("task 3")
}
print("Done!")
/*
Result
task 1
task 2
task 3
Done
*/
- queue์ ๋ค์ด๊ฐ ์์ ์ ์ฐ์ ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ฉด์ ๋์์ ๋๋๊ธธ ๊ธฐ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์ ํธ์ถ ์์๊ฐ ๋จ๋ฐฉํฅ์ด๋ค.
Serial Async Dispatch Queue
let queue = DispatchQueue.main
queue.async {
print("task 1")
}
queue.async {
print("task 2")
}
queue.async {
print("task 3")
}
print("Done???")
/*
Done??
Result
task 1
task 2
task 3
*/
- ํด๋น ์ฝ๋๊ฐ ์คํ๋๋ main thread์ ์์
์ ๋น๋๊ธฐ์ ์ผ๋ก ์ถ๊ฐํ์ฌ, ํ์ฌ ์ฝ๋๋ฅผ ์ฝ๋ ์์
๋ค์ ์ค์ผ์ฅด๋ง์ด ๋๋๋ก ๋ง๋ค์๋ค.
- Out โ ์ฝ๋ ์ฝ๊ธฐ task - task 1 - task 2 - task 3 โ In
- ๋ง์ฝ custom serial queue๋ก ํ๋ค๋ฉด ๋ณ๋ ฌ์ ์ผ๋ก ์์ ์ด ์คํ๋๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅด๋ค.
- async๋ก ์ค์ ํ ๊ฒฝ์ฐ, ํด๋น ๋ธ๋ฝ์ ์คํํ์ง ์๊ณ ์ ์ด๊ถ์ ๋๊ฒจ์ฃผ๊ฒ ๋๋ค.
- ๊ทธ๋์ ๋ผ์ธ์ ๋ชจ๋ ์ฝ๊ณ ํด๋น ๋ธ๋ฝ์ ์์ฐจ์ ์ผ๋ก ์คํ์์ผ ์์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
async
์ธ์๋ asyncAfter
๋ฉ์๋๋ ์๋ค.
-
Dispatch Time
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: { print("Executes after 2 seconds") })
- ๋๋ ธ์ด ์ ๋ฐ๋๋ก ์์คํ Clock์ ์๋์ ์ธ ์์
-
Dispatch Wall Time
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 2.0, execute: { print("Executes after 2 seconds") })
- ๋ง์ดํฌ๋ก์ด ์ ๋ฐ๋๋ก Wall Clock์ ์ ๋์ ์ธ ์์
- 5๋ถ ํ์ด๋จธ ๊ฑธ๊ณ , system ์๊ฐ์ 5๋ถ๋ค๋ก ์ค์ ํด๋ฒ๋ฆฌ๋ฉด ๋ฐ๋ก ํ์ด๋จธ ์๋
Concurrent Dispatch Queue
- ํ๋ ์ด์์ ์์ ์ ๋์์ ์คํ (์์ ์ด ๋ฌผ๋ฆฌ์ ์ค๋ ๋๋ก ์์ฐจ์ ์ผ๋ก ๋๊ฐ๋ ์๊ฐ์ ์์)
- ํ์ง๋ง ์์์ ํ์ ์ถ๊ฐ๋ ์์๋ก ์์
- ์์ ์ด ์๋ฃ๋์ง ์์๋๋ผ๋ Dequeueํ๋ค. ๋ฌผ๋ฆฌ์ ์ฝ์ด๊ฐ ๋จ์์์ ๊ฒฝ์ฐ, ์ ์์ ์ 1๋ฒ ์ฝ์ด์, ๊ทธ ๋ค ์์ ์ 2๋ฒ ์ฝ์ด์ ๋๊ธฐ๋ฉด ๋๊ธฐ ๋๋ฌธ์ด๋ค.
- ํน์ ์์ ์์ ์คํ๋๋ ๋ฌผ๋ฆฌ์ ์์ ์๋ ๊ฐ๋ณ์ ์ด๊ณ ์์คํ ํ๊ฒฝ์ ๋ฐ๋ผ ๋ค๋ฆ
์์ฑ ๋ฐฉ๋ฒ์ ์ญ์ 2๊ฐ๊ฐ ์๋ค.
- Global Queue
DispatchQueue.global()
- Custom Queue
DispatchQueue(label: "CustomConcurrentQueue", attributes: .concurrent)
Concurrent Sync Dispatch Queue
let queue = DispatchQueue.global()
queue.sync {
print("task 1")
}
queue.sync {
print("task 2")
}
queue.sync {
print("task 3")
}
print("Done!")
/*
Result
task 1
task 2
task 3
Done
*/
concurrent queue๋ก ์์ ๋ค์ด ๋ค์ด๊ฐ๊ฒ ๋๊ณ , concurrent queue์ sync๋ก ์์ ์ด ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ์ task๊ฐ ์๋ก ๋ค๋ฅธ ๋ฌผ๋ฆฌ์ ์ฝ์ด์๋ ์๋ํ๋๋ผ๋(์ฐ์ฐํ ๊ฐ์ ์ฝ์ด์ผ์๋ ์์) ๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ ํ์ ๋์ํ๋ค.
Concurrent Async Dispatch Queue
let queue = DispatchQueue.global()
queue.async {
print("task 1")
}
queue.async {
print("task 2")
}
queue.async {
print("task 3")
}
print("Done???")
/*
Result
task 2
task 1
task 3
Done???
*/
ํ์ฌ ๊ฒฐ๊ณผ๋ ์ด๋ ์ง๋ง, ๊ฐ task๊ฐ queue์ ๋ค์ด๊ฐ ํ, ์์คํ ํ๊ฒฝ๊ณผ ํ์ฌ ์ฝ์ด ํ์ฑ๋์ ๋ฐ๋ผ ๋์ํ๋ ์์๊ฐ ๋ฌ๋ผ์ง๋ค. ์ฆ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅ๋ฐ์ ์ ์๋ค.
์ฌ์ฉ ํจํด
-
Serial Queue(async) + Main Queue
let queue = DispatchQueue(label: "serial.queue") queue.async { // Do Some Long-Running Task DispatchQueue.main.async { // Update UI } }
-
Concurrent Queue(async) + Main Queue
DispathQueue.global().async { // Do Some Long-Running Task DispatchQueue.main.async { // Update UI } }
Quality of Service (QoS)
Apple์์ ์ ๊ณตํ๋ ์์ ์ ๋ช ์์ ์ธ ๋ถ๋ฅ
์ด ๋ถ๋ฅ๋ ์์ ์ค์ผ์ฅด๋ง ์, ์์ ์ ํ์ ์ ๋ฐ๋ผ ์ฐ์ ์์๋ฅผ ๋ค๋ฅด๊ฒ ํ๊ธฐ ์ํจ์ด๋ค. ์๋๋ ์ฐ์ ์์์ ๋ฐ๋ฅธ ๋ถ๋ฅ์ด๋ค. ์ฐ์ ์์๊ฐ ๋์ ์๋ก ๋ ๋ง์ ๋ฆฌ์์ค๋ก ๋ ๋น ๋ฅด๊ฒ ์ํํ๋ค. ์ง์ ์ Queue๋ฅผ ๋ง๋ค ๋, ํ๋ผ๋ฏธํฐ๋ก ์ ๋ ฅ ๊ฐ๋ฅํ๋ค.
- User Interactive
- ์ฌ์ฉ์์ ์ํธ์์ฉ์ด ํ์ํ ๋ ์ฌ์ฉ
- animations
- User Initiated
- ์ฌ์ฉ์๊ฐ ๋ฌด์ธ๊ฐ ์์ ์ ํ์ฌ ์ฆ๊ฐ์ ์ธ ๊ฒฐ๊ณผ๊ฐ ํ์ํ ๋ ์ฌ์ฉ
- Utility
- ๋ฐ์ดํฐ ๋ค์ด๋ก๋์ ๊ฐ์ด ์์ ์๋ฃ์ ์ค๋์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ๊ฒฝ์ฐ
- ๋๋ถ๋ถ์ ์์ ์์ ์ฌ์ฉ
- Background
- ๋๊ธฐํ ๋ฐ ๋ฐฑ์ ๊ณผ ๊ฐ์ด ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๋ ์์ ์ ํ ๋ ์ฌ์ฉ
- ์์ดํฐ์ ์ ์ ๋ ฅ ๋ชจ๋๋ก ์ค์ ํ ๊ฒฝ์ฐ, ์์ ์คํ์ด ๋์ง ์์ ์๋ ์๋ค.
QoS๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด default๋ก ์ง์ ๋๋๋ฐ, default๋ User Initiated์ Utility ์ฌ์ด์ ์กด์ฌํ๋ ์ค์๋๋ฅผ ๊ฐ์ง๋ค.
Dispatch Work Item
DispatchQueue ๋๋ DispatchGroup ์์์ ์ํํ ์์ ์ ์บก์ํ ํจ
item๋ด์์ ์คํ๊ฐ๋ฅํ๊ณ , dispatchQueue๋ก ๋๊ฒจ์ ์คํ์ด ๊ฐ๋ฅํ๋ค.
let item = DispatchWorkItem(block: {
print("task?")
})
item.perform() // ํ์ฌ ์ค๋ ๋์์ ์์
์ ๋๊ธฐ์ ์ผ๋ก ์ํ
item๋ด์์ perform์ผ๋ก ์ํํ๋ ๊ฒฝ์ฐ, ๋๊ธฐ์ ์ผ๋ก ์ํํ๊ธฐ ๋๋ฌธ์ ์์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
let item = DispatchWorkItem(qos: .utility, block: {
print("task")
})
DispatchQueue.global().async(execute: item)
ํน์ ์ด๋ ๊ฒ Queue์์ item ์์ฒด๋ฅผ ๋ฃ์ด์ ์คํ๋ ๊ฐ๋ฅํ๋ค. ์ด๊ฒฝ์ฐ๋ Queue๋ฅผ ์ง์ ํ๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์์๋ ๋๋ค.
wait
let item = DispatchWorkItem(block: {
for _ in 0..<100 {
print("task")
}
})
DispatchQueue.global().async(execute: item)
item.wait()
// ์์
๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆผ
print("Done!")
์์
์ global queue๋ก ๋๊ธฐ๊ณ ์ ์ด๊ถ์ ๋๊ฒจ๋ฐ์ ์ํ์์๋ ๋๊ธด ์์
(๋ค๋ฅธ ์ค๋ ๋์์ ์์
์ค)์ ๊ธฐ๋ค๋ฆด ์ ์๋ค. wait
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
notify
let item = DispatchWorkItem(block: {
for _ in 0..<100 {
print("task")
}
})
DispatchQueue.global().async(execute: item)
item.notify(queue: .main, execute: {
print("Done!")
})
print("task is running...")
notify
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด, ๋ค๋ฅธ ์ค๋ ๋์์ ๋์ํ๊ณ ์๋ ์์
์ด ๋๋ ๊ฒฝ์ฐ, ์ค์ ํด๋ ์์
์ ์คํํ ์ ์๋ค.
cancel
let item = DispatchWorkItem(block: {
for _ in 0..<100 {
print("task")
}
})
item.cancel()
print(item.isCancelled) // true
DispatchQueue.global().async(execute: item) // ๋์ํ์ง ์์
์์ง ์์
์ด ์ํ๋์ง ์์ ๊ฒฝ์ฐ cancel
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์
์ ์ทจ์ํ ์ ์๋ค. ์ทจ์๋ ๊ฒฝ์ฐ ์ค์ผ์ฅด๋ง ๋์ด๋ ๋์ํ์ง ์๋๋ค.
Dispatch Group
ํ๋ ์ด์์ ์์ ์คํ์ด ์๋ฃ๋ ๋๊น์ง ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ ๋ฐฉ๋ฒ
ํ ํ๋ฉด์ ๊ตฌ์ฑํ๊ธฐ ์ํด ์ฌ๋ฌ API ํธ์ถ, Model๋ก ํ์ฑํด์ผ ํ๋ ๊ฒฝ์ฐ, ํ๋์ ์์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ๋ ๊ฒ์ด ์ข๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ฉด ์ข๋ค. ์ฌ๋ฌ ์์ ์ ๊ทธ๋ฃน์ ์ฐ๊ฒฐํ๊ณ , ๋น๋๊ธฐ ์คํ์ ์ํด์ ์์ฝํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์ ์๋ค. ๋ชจ๋ ์์ ์ด ๋๋ ํ, Completion Handler๋ฅผ ํตํด ์๋ฃ ๋์์ ์คํํ ์ ์๋ค.
Enter/Leave
let group = DispatchGroup()
group.enter()
group.leave()
์ฌ๋ฌ ์์ ์ด ์์ ๋, ์์ํ๋ ์์ ์์ enter, ์์ ์ด ๋๋ฌ์ ๋ leave๋ฅผ ํด์ฃผ๊ฒ ๋๋ฉด, enter ์๋์ ์ฝ๋ ๋ธ๋ญ์ ํ๋๋ก ๋ฌถ์ ์ ์๋ค. ํ ์์ผ๋ก ์์ง์ธ๋ค. enterํ ๊ฒฝ์ฐ ๋ค์ด๊ฐ task count +1ํ๊ณ leaveํ ๋ -1 ํ๋ค.
Wait (Synchronous)
let group = DispatchGroup()
group.enter()
DispatchQueue.global().async {
for _ in 0..<100 {
// some code
}
print("task 1 is done")
group.leave()
}
group.enter()
DispatchQueue.global().async {
for _ in 0..<100 {
// some code
}
print("task 2 is done")
group.leave()
}
group.wait()
print("all tasks are done")
dispatchGroup์ wait๋ฅผ ์ ์ด์ฃผ๊ฒ ๋๋ฉด, enter๋ก ๋ค์ด๊ฐ task๋ค์ ์์ ์ด ๋ชจ๋ ๋๋ ์์ ์ ๋ค์ ๋ผ์ธ์ผ๋ก ๋์ด๊ฐ๋ค.
Notify (Asynchronous)
let group = DispatchGroup()
group.enter()
DispatchQueue.global().async {
for _ in 0..<100 {
// some code
}
print("task 1 is done")
group.leave()
}
group.enter()
DispatchQueue.global().async {
for _ in 0..<100 {
// some code
}
print("task 2 is done")
group.leave()
}
group.notify(queue: .main, execute: {
print("All tasks are done.")
})
print("passed the notify code line.)
notify๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, enter๋ก ๋ค์ด๊ฐ task๋ค์ ๊ฒฐ๊ณผ๊ฐ ๋ค ์๋ํ ๋ ์ฝ๋ ๋ธ๋ฝ์ด ์คํ๋๋, wait์ฒ๋ผ ๋๊ธฐ์ ์ผ๋ก ๋๊ธฐํ์ง ์๋๋ค. ๋น๋๊ธฐ๋ก ์ฝ๋ ๋ธ๋ฝ์ด ์คํ๋๋ค.
Without Enter/leave
let group = DispatchGroup()
DispatchQueue.global().async(group: group, execute: {
for _ in 0..<100 {
// some code
}
print("task 1 is done")
})
DispatchQueue.global().async(group: group, execute: {
for _ in 0..<100 {
// some code
}
print("task 2 is done")
})
group.notify(queue: .main, execute: {
print("All tasks are done.")
})
print("passed the notify code line.)
ํ๋ผ๋ฏธํฐ์ group ์์ฒด๋ฅผ ๋๊น์ผ๋ก์จ ๊ฐ์ ํจ๊ณผ๋ฅผ ๋ผ ์ ์๋ค. ๋ณด๋ค ์ฝ๋๊ฐ ๊น๋ํ๋ค.
Dispatch Source
์์คํ ์ด๋ฒคํธ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํ C๊ธฐ๋ฐ ๋ฉ์ปค๋์ฆ
- ๋ชจ๋ํฐ๋ง ํ ์ด๋ฒคํธ์ ํด๋น ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ DispatchQueue ๋ฐ ์ฝ๋๋ฅผ ์ง์ ํ๋ค.
- ์ด๋ฒคํธ ๋์ฐฉ ์ ์ง์ ํ ํ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์คํํ๋ค.
๋ฌด์จ ๋ง์ผ๊น..? ์ฝ์ด์๋ ์ ์๊ฐ ์๋ค.
- Timer Dispatch Sources
- ์ฃผ๊ธฐ์ ์ธ ์๋ฆผ์ ์์ฑ
- Signal Dispatch Sources
- UNIX Signal์ด ๋์ฐฉํ๋ฉด ์๋ฆผ
- Memory pressure sources
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋ ์๋ฆผ
- Descriptor sources
- ํ์ผ ๋ฐ ์์ผ ๊ธฐ๋ฐ ์์ ์๋ฆผ
- Process dispatch sources
- ํ๋ก์ธ์ค ๊ด๋ จ ์ด๋ฒคํธ ์๋ฆผ
- Mach port dispatch sources
- Mach ๊ด๋ จ ์ด๋ฒคํธ ์๋ฆผ
- custom dispatch sources
- ์ง์ ์ค์ ํ ํธ๋ฆฌ๊ฑฐ
์์
let source = DispatchSource.makeTimerSource(queue: .main)
source.setEventHandler {
print("main queue์์ 1์ด ๋ค์ ์คํ๋จ")
}
source.schedule(deadline: .now(), repeating: 1.0)
source.activate()
- Source๋ฅผ ๋ง๋ ๋ค. ์ด ๋ Queue๋ฅผ ์ง์ ํด์ค๋ค.
- ๊ทธ๋ฆฌ๊ณ ์ด๋ค ์์ ์ ์คํํ ๊ฒ์ธ์ง ํธ๋ค๋ฌ๋ฅผ ์ค์ ํด์ค๋ค.
- ์ค์ผ์ฅด๋ง ์กฐ๊ฑด์ ์ ํํ๋ค.
- ์คํํ๋ค.
์ ๋ฆฌ
- DispatchQueue
- Serial, Concurrent Queue๊ฐ ์กด์ฌํ๋ค.
- ๊ฐ๊ฐ์ ๋๊ธฐ, ๋น๋๊ธฐ์ ์ผ๋ก ์๋ํ๊ฒ ํ ์ ์๋ค.
- DispatchWorkItem
- dispatchQueue์์์ ์๋ํ ์์ ์ ์บก์ํ ํ ์ ์๋ค.
- DispatchGroup
- ์ฌ๋ฌ ์์ ๋ค์ ๋ฌถ์ด์ ๊ด๋ฆฌํ ์ ์๋ค. Block์์ผ์ ๋์์ํฌ ์ ์๋ค.
- DispatchSource
- ์์คํ ์ด๋ฒคํธ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์ด๋ค.
๋ค์ ๊ธ์์๋ Operation Queue์ ๋ํด์ ์์๋ณด๋๋ก ํ์.