Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- uikit toast
- rxdatasources
- swift 백준
- task cancellation
- domain data
- custombottomsheet
- paragraph style
- swift concurrency
- swift dashed line
- custom ui
- swift custom ui
- swift navigationcontroller
- identifiable
- Tuist
- BFS
- task cancel
- UIKit
- tusit font 추가 방법
- button configuration
- swift 점선
- DP
- SWIFT
- coordinator
- swift bottomsheet
- traits
- 타임라인 포맷팅
- RxSwift
- claen architecture
- reactorkit
- custom navigation bar
Archives
- Today
- Total
김경록의 앱 개발 여정
[Swift Concurrency] Structured Concurrency 구조적 동시성 본문
Swift Structured Concurrency
Swift의 Structured Concurrency는 비동기 작업을 계층적으로 구조화하여 코드의 가독성과 안전성을 높이는 방식이다. 이 개념 내에서 async let과 TaskGroup은 병렬 처리를 위한 핵심 도구로 사용된다.
1. async let 활용
개요
async let은 고정된 개수의 비동기 작업을 병렬로 실행할 때 사용된다. 선언된 async let은 즉시 실행되며, 이후에 await 키워드를 사용하여 결과를 기다릴 수 있다. 스코프를 벗어나기 전에 반드시 결과를 await해야 한다.
예시 코드
func fetchUser() async -> String {
try? await Task.sleep(nanoseconds: 1_000_000_000)
return "User"
}
func fetchPosts() async -> [String] {
try? await Task.sleep(nanoseconds: 2_000_000_000)
return ["Post 1", "Post 2"]
}
func loadData() async {
async let user = fetchUser()
async let posts = fetchPosts()
let (fetchedUser, fetchedPosts) = await (user, posts)
print("User: \\(fetchedUser), Posts: \\(fetchedPosts)")
}
특징
- 고정된 수의 비동기 작업에 적합
- 코드가 간결하며 사용이 직관적
- await는 반드시 해당 스코프 내에서 수행되어야 함
- 결과는 순서대로 병합 가능
2. TaskGroup 활용
개요
TaskGroup은 동적으로 생성된 복수의 비동기 작업을 그룹화하여 병렬로 실행할 수 있도록 한다. 작업 수가 가변적인 경우에 적합하며, 각 작업의 완료 시점에 따라 결과를 비동기적으로 수집할 수 있다.
예시 코드
swift
복사편집
func fetchItem(id: Int) async -> String {
try? await Task.sleep(nanoseconds: UInt64(1_000_000_000 / id))
return "Item \\(id)"
}
func fetchAllItems() async {
let ids = [1, 2, 3, 4, 5]
var results: [String] = []
await withTaskGroup(of: String.self) { group in
for id in ids {
group.addTask {
await fetchItem(id: id)
}
}
for await result in group {
results.append(result)
}
}
print("Results: \\(results)")
}
특징
- 작업 수가 유동적인 경우에 적합
- 각 작업은 group.addTask를 통해 추가
- for await를 통해 결과를 순차적으로 수집
- 에러 전파와 작업 그룹 전체 취소 기능을 지원
3. async let과 TaskGroup 비교
항목 async let TaskGroup
작업 개수 | 고정 | 유동적 |
코드 복잡도 | 낮음 | 비교적 높음 |
사용 용도 | 간단한 병렬 처리 | 복잡하고 동적인 병렬 작업 |
결과 수집 방식 | 튜플 등으로 동시에 수집 | for await로 순차적으로 수집 |
에러 처리 | try 사용 | try, throwing TaskGroup 지원 |
취소 처리 | 제한적 | 그룹 전체 취소 가능 |
공통점
- 부모 작업이 완료되기 전에 모든 자식 작업이 완료 되도록 기다림(어떤 경우에도 보장됨)
- 자식 작업의 우선 순위가 높아지면 부모 작업의 우선순위 또한 자동으로 높아짐
'TIL' 카테고리의 다른 글
[Swift Concurrency] 구조적 동시성의 취소(feat: 명시,암시적 취소전파) (0) | 2025.04.18 |
---|---|
[Swift Concurrency] Task의 취소 (0) | 2025.04.18 |
[Swift] Identifiable (0) | 2025.03.28 |
[RxSwift] Single<Void> 와 Completable (0) | 2025.03.13 |
[Clean Architecture] DTO와 도메인 모델의 차이와 분리해서 사용해야하는 이유 (0) | 2025.03.13 |