- ํ ํ๋ก์ ํธ (2์ธ)
- ๊ตฌํ ๊ธฐ๊ฐ : 2021.12.20 ~ 31 (2 weeks)
STEP 1 | STEP 2 | STEP 3 | STEP 4 |
---|---|---|---|
โ | โ | โ | โ |
๊ณ ๊ฐ ์ถ๊ฐ/์ด๊ธฐํ | ๊ณ ๊ฐ ์ฒ๋ฆฌ |
---|---|
์๋ฃ ๊ตฌ์กฐ | LinkedList |
---|---|
์ฅ์ | 1. ๋ฐ์ดํฐ ์ถ๊ฐ ๋ฐ ์ญ์ ๊ฐ ๋น ๋ฅด๋ค 2. ๋ฐ์ดํฐ ์ถ๊ฐ/์ญ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ๋ฐฐ์น๊ฐ ํ์์๊ธฐ์ ์ค๋ฒํค๋๊ฐ ๋ฎ๋ค |
๋จ์ | 1. ์ธ๋ฑ์ฑ(๊ฒ์)์ด ๋๋ฆฌ๋ค(O(n) ) |
ํ๋ก์ ํธ์์ ์๊ตฌ๋๋ LinkedList
์๋ฃ๊ตฌ์กฐ์ ๋ํด ์ดํด๋ณด์์ต๋๋ค. ์ํ์ ๋์ฐฉํ ๊ณ ๊ฐ์ ์์๋๋ก ์ฒ๋ฆฌ๋ ๊ฒ
์ด๋ผ๊ณ ์๊ฐํ์ฌ Singly Linked List
๋ฅผ ๊ตฌํํ ํ ์ด๋ฅผ ํ์ฉํ์ฌ Queue๋ฅผ ๊ตฌํํ์ต๋๋ค.
Node
ํ์
์ ๊ฒฝ์ฐ Linked List
์ ์ง์ ์ ์ผ๋ก ๊ด๋ จ๋ ํ์
์ผ๋ก, ์ธ๋ถ์์๋ ์ฌ์ฉ๋ ์ผ์ด ์์ ๊ฒ์ด๋ผ ์๊ฐํ์ฌ nested type์ผ๋ก ๊ตฌํํด์ฃผ์์ต๋๋ค.
class LinkedList<Element> {
class Node {
var value: Element
var next: Node?
init(value: Element) {
self.value = value
}
}
}
Queue
ํ์
์ ์ด๊ธฐํ ํ ๋๋ items
์ ์์๊ฐ ์๋ ๋น ๊ฒฝ์ฐ์ผ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ฌ items
๋ฅผ ์ต์
๋์ด ์๋ ๋น ๊ฐ์ผ๋ก ๋ง๋ค์ด์ฃผ์์ต๋๋ค.
-
Node๋ฅผ ํด๋์ค๋ก ๋ง๋ ์ด์
- Node ํ์ ์ ํ๋กํผํฐ์ธ next๊ฐ Node ํ์ ์ด์ด์ผ ํ๋ ์ํฉ, ์ฆ recursiveํ ๊ด๊ณ๋ฅผ ๊ฐ์ ธ์ผํ๊ธฐ ๋๋ฌธ์ class๋ฅผ ์ ํํ์ต๋๋ค.
- ๋ค์ ๋ ธ๋์ ๋ํ ์ฐธ์กฐ๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ class๋ฅผ ์ ํํ์ต๋๋ค.
-
LinkedList, Queue๋ฅผ ํด๋์ค๋ก ๋ง๋ ์ด์
- struct๋ก ๊ตฌํํ ๊ฒฝ์ฐ ๋จ์
- ๋ณ๊ฒฝ์ผ๋ก๋ถํฐ ์์ ํ์ง ์๋ค
- ์ฐ์ struct๋ก ๊ตฌํํ์ง ์์ ์ด์ ๋, ๋ด๋ถ์ ํ์ ์ด class์ด๊ธฐ ๋๋ฌธ์, ๊ฐ ํ์ ์์๋ ๋ถ๊ตฌํ๊ณ ๋ณ๊ฒฝ์ผ๋ก๋ถํฐ ์์ ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค.
- struct ํ์ ์ผ๋ก ๊ตฌํ๋ Linked List์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ ์ด๋ฅผ ๋ณต์ฌํ ํ, ๋ณต์ฌ๋ณธ ๋ด node์ ๊ฐ์ ๋ณ๊ฒฝํ๊ฒ ๋๋ฉด ์๋ณธ์ ๋ ธ๋ ๊ฐ์๋ ์ํฅ์ ๋ฏธ์น๊ฒ ๋ฉ๋๋ค.
- node๊ฐ class๋ก ๊ตฌํ๋์ด์๊ธฐ ๋๋ฌธ์ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๊ธฐ ๋๋ฌธ์ด๊ธฐ์ ๋ฐ์ํ ๋ฌธ์ ๋ก, ํด๋น ํ์ ์ struct๊ฐ ์๋ class๋ก ๊ตฌํํด์ฃผ์์ต๋๋ค.
- struct์์ class ํ์ ์ ๊ตฌํํ๊ฒ ๋๋ฉด struct์ ์ฅ์ ์ธ '๋ณ๊ฒฝ์ผ๋ก๋ถํฐ ์์ ํ๋ค'๋ ๊ฒ์ด ์ฌ๋ผ์ง๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
- ๋ํ ํน์๋ ์์ ์ธ์คํด์ค ๋ณต์ฌ์ ๋ํด์ ๋ฐ์ํ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ์ ์ ์ํ์์ต๋๋ค.
- ์์๋ก, Linked List๊ฐ struct์ผ ๋ ๋ค๋ฅธ ์ธ์คํด์ค๋ก ๋ณต์ฌ ํ ๋ด๋ถ node๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋ ๊ฒฝ์ฐ, node์ retain count๋ง 1๋งํผ ๋ด๋ ค๊ฐ๊ณ , node์ deinit์ด ํธ์ถ๋์ง ์์ต๋๋ค. ํ์ง๋ง ์ด๋ฅผ class๋ก ๊ตฌํํ ๊ฒฝ์ฐ, Linked List ์๋ณธ๊ณผ ๋ณต์ฌ๋ณธ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ ๊ฐ์, ์ด๋ ํ ๊ตฐ๋ฐ์ node๋ฅผ ์ง์ฐ๋๋ผ๋ ๋ชจ๋ ์ ๊ฑฐ๋์ด node์ deinit์ด ์ ์์ ์ผ๋ก ํธ์ถ๋จ์ ํ์ธํ์ต๋๋ค.
- ๋ณ๊ฒฝ์ผ๋ก๋ถํฐ ์์ ํ์ง ์๋ค
- ์ด๋ฌํ ์ด์ ์ ๊ทผ๊ฑฐํ์ฌ class๋ก ํด๋น ํ์ ์ ๊ตฌํํ์ต๋๋ค.
- struct๋ก ๊ตฌํํ ๊ฒฝ์ฐ ๋จ์
Linked List์ ๋ชจ๋ ๋ ธ๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ผ๋ก ์๋์ ๊ฐ์ด ๊ตฌํํด์ฃผ์์ต๋๋ค.
//์ต์ข
์ฝ๋
func removeAll() {
head = nil
tail = nil
}
์ฒ์์๋ ์์ฒ๋ผ ๊ตฌํํ ๊ฒฝ์ฐ head์ tail ์ฌ์ด์ ๋
ธ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๋ํ append
ํ๋ ๊ณผ์ ์์ ๋ณ์์ Node๋ฅผ ๋ฃ์ด ์ ์ธํ๋ ๊ฒ์ด ๋ณ์์ Node ์ธ์คํด์ค ์ฌ์ด์ ์ฐธ์กฐ ๊ด๊ณ๋ฅผ ๋ง๋ค์ด์ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋๋ค๊ณ ์๊ฐํ์์ต๋๋ค. ๊ทธ๋์ ์๋์ ๊ฐ์ด ๋ชจ๋ ๋
ธ๋๋ค์ ์ํํ๋ฉฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํด์ฃผ๋๋ก ๊ตฌํํ์ต๋๋ค.
func append(value: Element) {
let node = Node(value: value)
if let tailNode = tail {
tailNode.next = node
} else {
head = node
}
tail = node
}
//๊ณ ๋ฏผํ๋ ์ฝ๋
func removeAll() {
while let next = head?.next {
head = nil
head = next
}
head = nil
tail = nil
}
ํ์ง๋ง ๋ฉ์๋ ๋ด์ ์ง์ญ๋ณ์์ด๊ธฐ ๋๋ฌธ์ ํธ์ถ ์ข
๋ฃ์ ๋์์ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋๋ค๋ ๊ฒ์ ์ธ์งํ์์ต๋๋ค. ์ด์ Node ํ์
์ deinit์ ๊ตฌํํ์ฌ ํ์ธํด๋ณด๋ ๊ธฐ์กด removeAll
๋ฉ์๋ ์ฝ๋๋ง์ผ๋ก๋ ๋ชจ๋ node๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ์ํค๊ณ ์์์ ํ์ธํ์ต๋๋ค.
head๋ฅผ nil๋ก ๋ง๋ค์ด ์ค ๊ฒฝ์ฐ, ๊ฐ์ฅ ๋ง์ง๋ง ์ด์ ๋ ธ๋๊น์ง์ ๋ ธ๋๋ฅผ ์ญ์ ํด์ฃผ๊ฒ ๋ฉ๋๋ค. head๊ฐ ์ฌ๋ผ์ง๋ฉด์ head.next์ ๋ํ ์ฐธ์กฐ ๋ํ ๊นจ์ง๊ธฐ ๋๋ฌธ์ ์ฐ์์ ์ผ๋ก ๋ ธ๋๋ค์ด ์ฌ๋ผ์ง๋ ๊ฒ์ ํ์ธํ์ต๋๋ค.
์ด์ ๋ง์ง๋ง์ผ๋ก tail = nil
์ ํด์ฃผ์ด ๋ง์ง๋ง ๋
ธ๋๋ ์ ์์ ์ผ๋ก ์ ๊ฑฐํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ์์ต๋๋ค.
ํ ์คํธ ์ฝ๋๋ ์ข์ ์ฝ๋๋ก ์์ฑํด์ผํ๋์ง์ ๋ํ ๊ณ ๋ฏผ์ด ์์์ต๋๋ค.
๋ฐ๋ผ์ ์ฒ์์๋ ์ข์ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด, XCTestCase์์ sut ํ๋กํผํฐ๋ฅผ ์์์ ์ถ์ถ ์ต์ ๋ ํ์ ์ผ๋ก ์์ฑํ๊ธฐ๋ณด๋ค๋, ์ต์ ๋ ํ์ ์ผ๋ก ์์ฑํ์ฌ ๊ฐ ํ ์คํธ๋ง๋ค guard ๋ฌธ์ผ๋ก ์ต์ ๋์ ์ธ๋ํํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ์์ฑํ์ต๋๋ค.
๊ทธ๋ฌ๋, guard ๋ฌธ์ผ๋ก ์ธ๋ํํ๋ ๊ฒ์ด ๊ฐ๋ ์ฑ ์ธก๋ฉด์์ ์ข์ง ์๊ณ ํ ์คํธ ๋ชฉ์ ์ ๊ฐ๊ฒฐํ๊ฒ ๋ณด์ฌ์ฃผ์ง ๋ชปํฉ๋๋ค. ํ ์คํธ ์ฝ๋๋ ์ข์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ๋ณด๋ค๋ ํ ์คํธ ๋ก์ง ์์ฒด์ ์ง์คํด์ผํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ ์ธ๋ํ์ ์ฌ์ฉํด๋ ๋๋ค๋ ๊ฒฐ๋ก ์ ๋ด๋ ธ์ต๋๋ค.
class QueueTest: XCTestCase {
var sut: Queue<Int>!
}
func test_1์ด_๋ค์ด์๋_ํ์_peekํ์๋_๊ฐ๋ง_๋ฐํ๋๊ณ _1์ด_์ฌ๋ผ์ง์ง์๋์ง() {
sut.enqueue(value: 1)
let result = sut.peek()
XCTAssertEqual(result, 1)
XCTAssertFalse(sut.isEmpty)
}
sut ๋ฅผ ์ฌ์ฉํ๋ ๊ณณ์์ ๊ตณ์ด ์ธ๋ํํด์ฃผ์ง ์๊ณ ๊ฐ๊ฒฐํ๊ฒ ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ก์ต๋๋ค.
override๋ฅผ ํ๋ ๊ฒฝ์ฐ์ ํ์ ํด๋์ค๊ฐ ์์ ํด๋์ค์์ ์ง์ํ๋ ํด๋น ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋๋ก super.xxx
๋ฅผ ํธ์ถํ์์ต๋๋ค.
์ด ๋ถ๋ถ์ด SOLID ์์น ์ค LSP์ ๊ด๋ จ๋ ๊ฒ์ด๋ผ๋ ์ถ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ๋ฐ๊ณ OOP์ ์ธ ๊ด์ ์์ ๋ค์๊ธ ์๊ฐํด๋ณด๊ฒ ๋์์ต๋๋ค.
์์ ์ธ๊ธ๋ ๋ถ๋ถ์ฒ๋ผ ํ
์คํธ ์ฝ๋์์๋ OOP ๊ด์ ์ผ๋ก ์๊ฐํ์ง ์๊ณ ๋ฌด๊ฒฐ์ฑ์ ์ฐ์ ์ํด์ผํ๊ธฐ ๋๋ฌธ์ ๊ด๋ จ๋ ๋ฉ์๋์์super.xxx
๋ฅผ ํธ์ถํ์ง ์์๋ ๋๋ค๋ ๊ฒ์ ์ธ์งํ์ต๋๋ค.
๊ฐ์ฒด๋ค์ ๊ฐ๊ฐ ์ญํ ๊ณผ ์ฑ ์์ ๊ฐ๊ณ , ์๋ก ๋ฉ์์ง(์์ฒญ)๋ฅผ ๋ณด๋ด ํ๋ ฅํ ์ ์๋๋ก ๊ตฌํํด๋ณด๊ณ ์ ํ์ต๋๋ค.
BankClerk
(= ์ํ์)- ๊ณ ๊ฐ ์ ๋ฌด ์ฒ๋ฆฌ ์งํ
- ์ํ์๊ฒ ์ ๋ฌด ๋ง๊ฐ์ ์๋ฆผ
Bank
(= ์ํ)- ๊ณ ๊ฐ queue ๋ณด์
- ์ํ์์๊ฒ ์ผ์ ์์ํ ๊ฒ์ ์๋ฆผ
- ์ํ ์ ๋ฌด ์ข ๋ฃ ๊ด๋ฆฌ
BankManager
- ์ํ ๊ฐ์
- ์ํ์ ๊ณ ๊ฐ queue๋ฅผ ์ฑ์ฐ๋ ๊ธฐ๋ฅ
- ์ฌ์ฉ์์๊ฒ ์ถ๋ ฅ๋๋ ๊ธฐ๋ฅ ๋ด๋น
Customer
(= ๊ณ ๊ฐ)- ๋๊ธฐ์ด ๋ฒํธ ๋ณด์
- ์ ๋ฌด ์ฒ๋ฆฌ์ ์์๋๋ ์๊ฐ ๋ณด์
์๊ตฌ์ฌํญ์์๋ ์ํ/๊ณ ๊ฐ ํ์ ๋ง ์์์ง๋ง, ์ํ ๋ด์์ ์ค์ง์ ์ผ๋ก ์์ ์ ์ฒ๋ฆฌํ๋ ์ํ์ ํ์ ์ ์ถ๊ฐํด๋ดค์ต๋๋ค.
๋ํ ์ต๋ํ ์ ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฝ๋๋ก ์ฎ๊ฒจ๋ณด๋ ค๊ณ ๋ ธ๋ ฅํ์ต๋๋ค.
๋ ๊ฐ์ง ๋ถ๋ถ์ ๋ํด Delegate ํจํด์ ์ฌ์ฉํ์์ต๋๋ค.
Bank
<->BankClerk
: ์๋ก ์์ ์ ์์ฒญํ๊ณ , ์์ ์ด ์ข ๋ฃ๋จ์ ์๋ฆฌ๊ธฐ ์ํด ์ฌ์ฉํ์ต๋๋คBank
์BankClerk
->BankManager
(BankDelegate
,BankClerkDelegate
ํ๋กํ ์ฝ ์ฑํ) :Bank
์BankClerk
๊ฐ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค ๋ฉ์ธ์ง๋ฅผ ์ง์ ํ๋ฆฐํธํ์ง ์๊ณBankManager
์์ ๋์ ํด์ฃผ๊ธฐ ์ํด ์ฌ์ฉํ์ต๋๋ค. (์ถํ UIApp์ผ๋ก ์ ํ์, ํ์ฌ print๋๊ณ ์๋ ๋ถ๋ถ๋ค์ด UI์์์ ์ฐ๊ฒฐ๋ ๋ถ๋ถ์ด๋ผ๊ณ ์๊ฐํ์์ต๋๋ค.)
Bank
์ BankClerk
๊ฐ ์๋ก ์ฐธ์กฐํ๊ณ ์๋ ๊ตฌ์กฐ๊ฐ ๋์ด ์ํ ์ฐธ์กฐ๊ฐ ๋ฐ์ํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ ์ ์์๊ฑฐ๋ผ ์๊ฐํ์ต๋๋ค.
์ด์ BankClerk
๊ฐ ๊ฐ์ง๋ bank
๋ฅผ weak
๋ก ๊ตฌํํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํด์ฃผ์์ต๋๋ค.
์ํ์์ ์๋ฅผ ์ฐ๋ ๋๋ผ๊ณ ์๊ฐํ์๊ณ , ๊ณ ๊ฐ์ ์ ๋ฌด ์ข ๋ฅ์ ๋ฐ๋ผ depositQueue, loanQueue๋ฅผ ๋ง๋ค์ด์ฃผ์์ต๋๋ค. depositQueue๋ concurrentํ๊ฒ loanQueue๋ serialํ๊ฒ ๋ง๋ค์์ต๋๋ค.
while๋ฌธ์ ์กฐ๊ฑด์ผ๋ก customerQueue์์ customer์ dequeueํ๋ ๊ฒ์ ์ค์ ํ์ฌ ๊ณต์ ์์์๋ ํ ๋ฒ์ฉ๋ง ์ ๊ทผํ๋๋ก ์ค๊ณํ์์ต๋๋ค.
deposit ์ผ์ด์ค์์๋ ๋น๋๊ธฐ์ ์ผ๋ก ๋์ํ๋ concurrent ํ์์ semaphore๋ฅผ ์ฌ์ฉํ์ฌ ๋์์ ์ ๊ทผ๊ฐ๋ฅํ ์ค๋ ๋์ ์๋ฅผ 2๋ก ๋์ด์ deposit์ ์ฒ๋ฆฌํ๋ ์ํ์์ด ๋์์ ๋๋ช ์ด ๋๋๋ก ๊ตฌํํ์์ต๋๋ค.
๋ฐ๋ฉด์ loan ์ผ์ด์ค์์๋ ์ผ์ ์ฒ๋ฆฌํ๋ ์ํ์์ด ํ ๋ช ์ด๊ธฐ๋๋ฌธ์ ๋น๋๊ธฐ์ ์ผ๋ก ๋์ํ๋ serialํ๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
static func createRandomTask() -> Self {
guard let task = Self.allCases.randomElement() else {
fatalError("๋๋คํ Task๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.")
}
return task
}
Task
enum๋ด์ ๋๋คํ task๋ฅผ ์ด๊ฑฐํ์ ๋ชจ๋ case์์ ๊ณจ๋ผ์ ๋ฆฌํดํด์ฃผ๋ ๋ฉ์๋์์ fatalError()์ ์ฌ์ฉํ์๋๋ฐ์, ์ฒ์์๋ error enum์ ๋ฐ๋ก ๋ง๋ค์ด์ค์ ์๋ฌ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๋ ค๊ณ ํ์ง๋ง, ๋ก์ง์ ์ ๋ ๋ฐ์ํ ์ ์๋ ์๋ฌ๋ผ๊ณ ํ๋จํ์ฌ fatalError๋ก ๊ตฌํํ์์ต๋๋ค. (apple์ด ๊ฒ์ฆํ ๋ฉ์๋๋ผ๊ณ ์๊ฐํ์ต๋๋ค.)
์์ ๊ณ ๋ฏผํ๋ ๋ถ๋ถ์ ๋ฐ๋ผ ๊ตฌํํ๋ค ๋ณด๋ BankClerk๊ฐ delegate ํจํด์ ํตํด Bank๋ฅผ ์๊ฒํ๋ ๋ฐฉ์์ด ํ์์๊ฒ ๋์์ต๋๋ค. ์ด์ ์ด ๊ด๊ณ๋ฅผ ์ ๊ฑฐํด์ฃผ์๊ณ , ๊ธฐ์กด customer queue์์ dequeueํ๋ ๋ถ๋ถ์ Bank๊ฐ ํ๋๋ก ์ด์ ํ์์ต๋๋ค.
๊ธฐ์กด์๋ BankClerk๊ฐ ์ฒ๋ฆฌํ๋ ๊ณ ๊ฐ์ ์์ ์๊ฐ์ ์ผ์ผ์ด ํฉํ์ฌ ์ด๋ฅผ ๊ณ์ฐํ์๋๋ฐ, ์์คํ
์๊ฐ์ ํ์ฉํ์ฌ ๊ฐ์ ํ์์ต๋๋ค. CFAbsoluteTimeGetCurrent()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์/๋ ์๊ฐ์ ๊ธฐ๋กํ๊ณ ์ด ์๊ฐ๋ค์ ์ฐจ๋ฅผ ์ด ์
๋ฌด์๊ฐ์ผ๋ก ํ์์ต๋๋ค. ๊ทธ๋ฌ๋, ์์คํ
์๊ฐ์ ์ธ๋ถ ์๊ฐ ์ฐธ์กฐ์์ ๋๊ธฐํ ๋๋ ์ฌ์ฉ์๊ฐ ์์คํ
์๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ ๊ฐ์ํ ์ ์๊ธฐ๋๋ฌธ์ DispatchTime
๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๊ฐ์ ํ์์ต๋๋ค.
// ๊ธฐ์กด ๋ฐฉ์
let startTime = CFAbsoluteTimeGetCurrent()
let endTime = CFAbsoluteTimeGetCurrent()
let totalProcessingTime = endTime - startTime
// ๊ฐ์ ๋ฐฉ์
let startTime = DispatchTime.now()
let endTime = DispatchTime.now()
let totalProcessingTime = Double(endTime.uptimeNanoseconds - startTime.uptimeNanoseconds)
Queue์์ ๋งจ ์ฒ์ ์์๋ฅผ ์ ๊ฑฐํ์ง ์๊ณ ํ์ธ๋ง ํ๋ peek()
๋ฅผ ํตํด customer์ task๋ฅผ ํ์ธํ๊ณ ๊ฐ๊ฐ์ queue์ ํ ๋น ํ ํ ๊ฐ ์ฐ๋ ๋ ๋ด์์ customerQueue์ ์ ๊ทผํ์ฌ dequeueํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํด๋ณด๋ ค ์๋ํ์ต๋๋ค.
๊ทธ๋ฌ๋ค๊ฐ while๋ฌธ์ด ๋น์ ์์ ์ผ๋ก ๋ง์ด ๋๋ฉฐ ํ๋ก๊ทธ๋จ์ด ์ ๋๋ก ์๋ํ์ง ์์์, ๊ฐ queue์์ customerQueue์ ๋์์ ์ ๊ทผํ๋ ์ํฉ์ด ์์ ์๊ฒจ๋์ง ์๋๋ก customerQueue.dequeue()
๋ก ๋ฆฌํดํ ์์๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ๋ ๋ก์ง์ผ๋ก ๊ฐ์ ํ์์ต๋๋ค.
func open() {
let group = DispatchGroup()
let depositQueue = DispatchQueue(label: "deposit", attributes: .concurrent)
let loanQueue = DispatchQueue(label: "loan")
let semaphore = DispatchSemaphore(value: 2)
while !customerQueue.isEmpty {
switch customerQueue.peek()?.task {
case .deposit:
depositQueue.async(group: group) {
semaphore.wait()
self.bankClerk.work() //์ฌ๊ธฐ์ dequeue๋ฅผ ํ๋ค.
semaphore.signal()
}
case .loan:
loanQueue.async {
self.bankClerk.work() //์ฌ๊ธฐ์ dequeue๋ฅผ ํ๋ค.
}
default:
return
}
}
group.wait()
}
func open(timer: BankTimer) {
timer.start()
let group = DispatchGroup()
let semaphore = DispatchSemaphore(value: 2)
let depositQueue = DispatchQueue(label: "deposit", attributes: .concurrent)
let loanQueue = DispatchQueue(label: "loan")
let bankGroup = DispatchGroup()
while let customer = customerQueue.dequeue() {
switch customer.task {
case .deposit:
depositQueue.async(group: group) {
semaphore.wait()
self.bankClerk.work(with: customer)
semaphore.signal()
}
case .loan:
loanQueue.async(group: group) {
self.bankClerk.work(with: customer)
}
}
}
group.notify(queue: DispatchQueue.main) {
timer.stop()
}
}
UI๋ฅผ ์ ๋ฐ์ดํธ ํ๋ ์ฝ๋๋ค์ ๋ชจ๋ main ์ฐ๋ ๋ ๋ด์์ ์งํํด์ฃผ์์ต๋๋ค. ์ด์ ๋ฌธ์ ์์ด ์๋ํ๋ ์ ํ์ธํ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ํ ์ ๋ฌด๊ฐ ์งํ๋๋ ์ฐ๋ ๋๋ custom queue(serial/concurrent)์ด๊ธฐ์ UI์ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ฐ๋ ๋์ธ ๋ฉ์ธ ์ฐ๋ ๋์์ ์ ์์ ์ผ๋ก ์ ๋ฐ์ดํธ ํ๋๋ก ๊ตฌํํ์ต๋๋ค.
์์ฃผ ์ฐ์ด๋ UIStackView
๋ UILabel
, UIButton
๋ค์ ์ปค์คํ
๋ทฐ๋ก ๊ตฌํํ์ฌ ์ฌ์ฉํ์ต๋๋ค. ์ปค์คํ
๋ทฐ๋ฅผ ๋ง๋ค ๋ ํ์ํ ์์ฑ์ ์ด๋์
๋ผ์ด์ ๋ฅผ ํตํด ๊ฐ๋จํ๊ฒ ์์ฑํ ์ ์๋๋ก ํ์ต๋๋ค.
์ถ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ํตํด ์ปค์คํ
๋ทฐ๋ฅผ ๋ง๋ค๊ธฐ ๋ณด๋ค๋ ํด๋ก์ ๋ฐฉ์์ผ๋ก UI์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๋ฐฉ์์ด ๋ ํจ์จ์ ์ด๋ผ๋ ๊ฒ์ ํ์ธํ๊ณ ์ถํ ๋ฐ์ํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
Bank ํ์
์ open()
๋ฉ์๋์์ DispatchGroup์ ์ฌ์ฉํ์ฌ group์์ ๋ค์ด๊ฐ ์์
๋ค์ด ๋ชจ๋ ๋๋ ๋ ๋น๋๊ธฐ์ ์ผ๋ก timer์ stop ๋ฉ์๋๊ฐ ํธ์ถ๋๋๋ก ๊ตฌํํ์์ต๋๋ค.
์ฒ์์๋ Bank์ open()
๋ฉ์๋์์ ๋ง์ง๋ง ๋ผ์ธ์ group.wait()
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์ธ ์ฐ๋ ๋๋ฅผ ๋ธ๋กํ์๋๋ฐ, ์ด ๋๋ฌธ์ ๋ชจ๋ ์์
์ด ์๋ฃ๋๊ณ ๋์์ผ UI๊ฐ ํ๊บผ๋ฒ์ ์
๋ฐ์ดํธ ๋๋ ์ํฉ์ด ๋ฐ์ํ์์ต๋๋ค. ์ด์ ๋์์ UI ๋ํ ์
๋ฐ์ดํธ๋ฅผ ์์ผ์ฃผ๊ธฐ ์ํด, ์์
์ ๋๊ธฐ์ ์ผ๋ก ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋น๋๊ธฐ์ ์ผ๋ก ๊ธฐ๋ค๋ ค์ฃผ๋๋ก ์์ ํ์ต๋๋ค.
์ด ๋ dispatchGroup์์ wait()
๋ synchronous ํ๊ฒ ๋์ํ๊ณ , notify()
์ ๊ฒฝ์ฐ asynchronous ํ๊ฒ ๋์ํ๋ค๋ ๊ฒ์ ์ด์ฉํ์ฌ notify()
๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
group.notify(queue: DispatchQueue.main) {
timer.stop()
}
์ฝ๋๋ก ํ๋ฉด์ ๊ทธ๋ฆด ๋ ์ต๋ํ stackView๋ฅผ ํ์ฉํ์ฌ ๊ตฌ์ฑํด๋ณด๋ ค๊ณ ๋
ธ๋ ฅํ์ต๋๋ค. ์ด ๋๋ถ์ ๊ฐ๋ณ UI์์์ auto layout์ ์ ์ฉํ๋ ๊ฒ๋ณด๋ค ๊ณต์๊ฐ ๋ ๋ค๊ฒ ๋ ๊ฒ ๊ฐ์ ์ด์ ์ ์ทจํ๋ค๊ณ ์๊ฐํ์ต๋๋ค! ์ถ๊ฐ ํผ๋๋ฐฑ์ ํตํด UIStackView
, Auto layout์ ์ฑ๋ฅ์ ํ์ธํ์ผ๋ฉฐ ์ฒด๊ณ์ ์ผ๋ก ์ ์ฌ์ฉํด์ผ๊ฒ ๋ค๊ณ ์๊ฐํ์ต๋๋ค.