๋ฐฑํ๋ ์ ๊ด๋ฆฌ๋ ์ฃผ๋ก ๋ฐฑ์๋์์ ํ์ง๋ง Combine ํ๋ ์์ํฌ๋ฅผ ํ์ฉํด์ iOS ๋จ์์๋ ๊ด๋ฆฌ๋ฅผ ํด์ค ์ ์๋ค. ์ฌ๊ธฐ์ ๋ฐฑํ๋ ์ ๋ ์๋ฒ๋ก๋ถํฐ ๋ ๋ผ์ค๋ ๋ฐ์ดํฐ ์๋๋ฅผ, ์ปด๋ฐ์ธ์ผ๋ก ํ์ ์ง์ผ๋ฉด ์ ์คํธ๋ฆผ์์ ๋ ๋ผ์ค๋ ๋ฐ์ดํฐ ์๋๋ฅผ ๋ค์ด์คํธ๋ฆผ์ ์ฒ๋ฆฌ์๋๊ฐ ๋ฐ๋ผ๊ฐ์ง ๋ชปํด ๋ฐ์ํ๋ ๋ฌธ์ ๋ก ์์ ์ํฉ์ผ๋ก๋ ์๋์ ๊ฐ๋ค.
- ๋น๋๊ธฐ ๋ฐ์ดํฐ ๋ก๋ฉ
iOS ์ฑ์์ ์ธ๋ถ API๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก๋ถํฐ ๋น๋๊ธฐ์ ์ผ๋ก ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ ๋, ๋คํธ์ํฌ ์ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ต ์๋์ ๋ฐ๋ผ ๋ฐ์ดํฐ๊ฐ ๋๋ฌด ๋นจ๋ฆฌ ๋์ฐฉํ๋ฉด, ์ฑ์ ๋ฉ์ธ ์ค๋ ๋๊ฐ ๋ธ๋ก๋๊ฑฐ๋ UI๊ฐ ๋๋ ค์ง ์ ์๋ค. - ์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ
์ค์๊ฐ์ผ๋ก ๋ง์ ์์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ ์ฑ(์: ๊ธ์ต ์ฑ์์์ ์ฃผ์ ๊ฐ๊ฒฉ ์ ๋ฐ์ดํธ, ์คํฌ์ธ ์ฑ์์์ ์ค์๊ฐ ์ ์ ์ ๋ฐ์ดํธ)์์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ฐฑํ๋ ์ ๋ฅผ ๊ด๋ฆฌํ์ง ๋ชปํ๋ฉด ์ฑ์ด ๋๋ ค์ง๊ฑฐ๋, ์ต์ ์ ๊ฒฝ์ฐ ์๋ตํ์ง ์์ ์ ์๋ค. - ๋์ฉ๋ ํ์ผ ๋ค์ด๋ก๋
์ฌ์ฉ์๊ฐ ๋์ฉ๋ ํ์ผ์ ๋ค์ด๋ก๋ํ๊ฑฐ๋ ๋์์์ ์คํธ๋ฆฌ๋ฐํ ๋, ๋คํธ์ํฌ ์ํ์ ์ฅ์น์ ์ ์ฅ ๊ณต๊ฐ ๊ด๋ฆฌ๊ฐ ๋ฐฑํ๋ ์ ๋ฌธ์ ์ ์ง์ ์ ์ผ๋ก ๊ด๋ จ๋ ์ ์๋ค. ๋ค์ด๋ก๋ ์๋๊ฐ ์ฅ์น์ ์ ์ฅ ์ฒ๋ฆฌ ์๋๋ฅผ ์ด๊ณผํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ด๋ฌํ ๋ฌธ์ ์ํฉ์ด ๋ฐ์ํ ๊ฒฝ์ฐ ์ปด๋ฐ์ธ์ Subscribers.Demand (๊ตฌ๋ ์๊ฐ ํผ๋ธ๋ฆฌ์ ์๊ฒ ์์ฒญ ํญ๋ชฉ ์ ์กฐ์ ) ์ ํตํด ๋ฐฑํ๋ ์ ๋ฅผ ๊ด๋ฆฌํด์ค ์ ์๋ค.
// ์์ ์คํ์ ์ํ ํจ์
func example(of description: String, action: () -> Void) {
print("\n--- Example of:", description, "---")
action()
}
// ์ฒซ ๋ฒ์งธ ์์ : ์ผ๋ฐ์ ์ธ sink ์ฌ์ฉ
example(of: "Backpressure Issue") {
let publisher = (1...10).publisher
let startTime = Date()
publisher
.sink(receiveCompletion: { completion in
let processTime = Date().timeIntervalSince(startTime)
print("Completed with: \(completion) after \(processTime) seconds")
}, receiveValue: { value in
let processTime = Date().timeIntervalSince(startTime)
print("Received value \(value) at \(processTime) seconds")
sleep(1) // ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๊ฐ
})
}
// ๋ ๋ฒ์งธ ์์ : Subscriber๋ฅผ ์ฌ์ฉํ ๋ฐฑํ๋ ์
๊ด๋ฆฌ
example(of: "Handling Backpressure with IntSubscriber") {
final class IntSubscriber: Subscriber {
typealias Input = Int
typealias Failure = Never
var startTime = Date()
func receive(subscription: Subscription) {
subscription.request(.max(1)) // ์ด๊ธฐ ๋ฐ์ดํฐ ์์ฒญ
startTime = Date() // ์์ ์๊ฐ ์ด๊ธฐํ
}
func receive(_ input: Int) -> Subscribers.Demand {
let processTime = Date().timeIntervalSince(startTime)
print("Received value \(input) at \(processTime) seconds")
if input % 2 == 0 {
sleep(2) // ์ง์์ผ ๋๋ ์ฒ๋ฆฌ ์๊ฐ์ ๋ ๊ธธ๊ฒ
return .max(2) // ๋ ๋ง์ ๋ฐ์ดํฐ ์์ฒญ
} else {
sleep(1) // ํ์์ผ ๋๋ ๊ธฐ์กด๊ณผ ๋์ผ
return .max(1) // ๊ธฐ๋ณธ ๋ฐ์ดํฐ ์์ฒญ
}
}
func receive(completion: Subscribers.Completion<Never>) {
let processTime = Date().timeIntervalSince(startTime)
print("Completed with: \(completion) after \(processTime) seconds")
}
}
let publisher = (1...10).publisher
let subscriber = IntSubscriber()
publisher.subscribe(subscriber)
}
์์ ์ฝ๋์์๋ ์ผ๋ถ๋ฌ sleep ์ ์คํ์์ผ ์ธ์์ ์ผ๋ก ์ฒ๋ฆฌ ์๊ฐ์ ์ง์ฐ์์ผฐ๋ค. 2์ด๊ฐ ์ง์ฐ๋จ์๋ 1์ด๊ฐ ๋ฐ์ดํฐ๊ฐ ๊ณ์ ๋ ๋ผ์ค๊ณ ์๊ธฐ ๋๋ฌธ์ BackPressure ๊ด๋ฆฌ๋ฅผ ์ํด max(2)๊ฐ์ฉ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํจ์ผ๋ก์จ ํ๋ก ํธ๋จ์์ ๋ถ์กฑํ ์๋๋ฅผ ๋ณด์ํด์ฃผ์๋ค.
https://www.kodeco.com/21773708-intermediate-combine/lessons/3
'๐ฆ Flutter' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| Combine | 12. Retrying and Catching Errors (0) | 2024.05.15 |
---|---|
| Combine | 11. Mapping Errors (0) | 2024.05.14 |
| Combine | 9. Networking with Combine (0) | 2024.05.14 |
| Combine | 8. Sequencing Operators (0) | 2024.05.13 |
| Combine | 7. Scheduling Operators (0) | 2024.05.13 |