Swift Concurrency. Explore Structured Concurrency in Swift (1) - WWDC21

앞서 정리한 세션에서는 completion handler 기반의 비동기 코드를 async/await로 작성하면서, 비동기 코드에서도 return, throw, try-catch와 같은 일반적인 제어 흐름을 사용할 수 있게 되었다. 이번 포스팅에서는 WWDC21의 Explore Structured Concurrency in Swift 세션을 정리한다. async/await가 비동기 코드의 제어 흐름을 구조화했다면, structured concurrency는 여기서 더 나아가 동시에 실행되는 여러 task의 관계와 수명을 구조화한다. Explore Structed Concurrency in Swift Swift Concurrency는 구조화된 프로그래밍(structured programming)의 아이디어에 기반한 structured concurrency라는 개념을 활용한다. 옛날에는 프로그램에서 명령어를 나열하고, 컨트롤 플로우가 여기저기로 자유롭게 점프해서 코드를 읽기가 매우 어려웠다. (C의 goto를 생각해보자) ...

August 15, 2026

Swift Concurrency. Meet async/await in Swift (2) - WWDC21

1편에서는 async await를 어떻게 사용했는지 알아봤다면, 여기서는 테스트와 실제 앱 코드에서 async/await를 사용하는 법을 알아본다. 또한 기존에 존재하는 completion handler 기반 API를 continuation을 사용하여, async/await를 사용하는 async alternative로 변환하는 방법을 알아본다. 비동기 코드 테스트하기 async/await를 쓰면 비동기 코드도 동기 코드만큼 쉽게 테스트할 수 있다. XCTest는 async 테스트를 지원한다. 아래는 completion handler 방식의 비동기 코드를 테스트하는 코드이다. class MockViewModelSpec: XCTestCase { func testFetchThumbnails() throws { let expectation = XCTestExpectation(description: "mock thumbnails completion") self.mockViewModel.fetchThumbnail(for: mockID) { result, error in XCTAssertNil(error) expectation.fulfill() } wait(for: [expectation], timeout: 5.0) } } ifulfill fulfill()은 expectation을 충족된 상태로 표시하는 메소드다. 일반적으로 비동기 작업이 완료되었을 때 호출한다. 기존에는 XCTestExpectation을 만들고, API를 호출한 뒤 expectation을 fulfill 하고, 지정한 시간 동안 기다리도록 작성해야 했다. ...

August 3, 2026

Swift Concurrency. Meet async/await in Swift (1) - WWDC21

completion handler로 작성한 비동기 코드는 쉽게 장황해지고, 복잡해지고, 부정확해진다. Swift의 async/await는 비동기 코드를 일반 코드를 작성하는 것처럼 만들어 주고, 아이디어를 더 쉽게 반영하며, 더 안전하게 만든다. async/await는 단순한 비동기 표현 방식이 아니다. 이 세션에서는 async/await가 왜 기존 completion handler 방식보다 좋은지, 그리고 Swift의 컨셉에 왜 잘 맞는지를 계속해서 설명한다. Meet async/await in Swift Foundation 같은 Apple SDK에는 await할 수 있는 수백 개의 메소드가 존재한다. UIKit의 UIImage는 섬네일을 만드는 API를 동기 방식과 비동기 방식으로 모두 제공한다. ...

August 3, 2026

Swift Concurrency. Behind the Scenes - WWDC21

Threading model 뉴스 피드 리더 앱을 예로 들어보자. 앱의 상위 컴포넌트는 다음과 같이 나눌 수 있다. 사용자 인터페이스를 담당하는 메인 스레드 사용자가 구독한 뉴스 피드를 추적하는 데이터베이스 최신 콘텐츠를 가져오는 네트워킹 서브시스템 사용자가 최신 뉴스를 요청하면 다음과 같은 흐름으로 처리할 수 있다. 메인 스레드에서 이벤트 제스처 처리 데이터베이스 작업을 처리하는 직렬 큐로 요청을 비동기적으로 디스패치 작업을 다른 큐로 보내면 메인 스레드는 데이터베이스 작업을 기다리지 않고 사용자 입력에 계속 반응할 수 있다. 직렬 큐가 상호 배제를 보장하므로 데이터베이스 접근을 순서대로 처리할 수 있다. 데이터베이스 큐에선 사용자가 구독한 피드에 URLSession을 통해 콘텐츠를 다운로드하는 네트워크 요청을 스케줄링 결과가 도착하면 URLSession의 콜백이 Delegate Queue 위에서 호출되어서 각 결과의 Completion Handler가 동기적으로 데이터베이스를 업데이트한다. MainThread를 깨워서 UI를 리프레시한다. 보기에는 합리적인 방법이다. 메인 스레드를 블록하지 않으면서 네트워크 요청을 동시에 처리할 수 있기 때문이다. ...

August 25, 2025

Swift Concurrency. 01. 도입 배경

Swift Concurrency는 Swift 5.5에서 도입된 기능이다. Foundation을 import 해야 쓸 수 있는 GCD와 다르게, Swift 언어 자체에 내장된 동시성 모델이다. Swift Concurrency는 크게 두 가지 부분으로 나뉘어진다. async, await 로 작성하는 새로운 동시성 모델 애플리케이션을 여러 동시성 태스크로 분할하는 Actor 이 포스트에서는 Swift Concurrency의 도입 배경을 알아본다. GCD의 한계 GCD는 Objective-C에서부터 사용해온 애플이 만든 비동기 API다. Queue 기반으로 작업을 스케줄링 하고, 스레드 위에서 추상화 되어있기 때문에 스레드를 직접 생성하거나 관리할 필요가 없다. ...

August 3, 2025

프로세스와 스레드

프로세스 컴퓨터에서 실행 중인 프로그램의 인스턴스, 프로그램이 메모리에 올라가면 프로세스가 된다. 프로세스의 상태 운영체제마다 세부 상태는 다르지만, 기본적인 5상태 모델은 다음과 같다. 생성(New): 프로세스가 만들어지는 중인 상태 준비(Ready): 실행에 필요한 자원을 갖추고 CPU 할당을 기다리는 상태 실행(Running): CPU에서 명령을 실행하고 있는 상태 대기(Waiting, Blocked): I/O 완료나 이벤트 발생을 기다리는 상태 종료(Terminated): 실행이 끝난 상태 CPU 스케줄러가 준비 상태의 프로세스를 선택하면 실행 상태로 이동한다. 할당 시간이 끝나거나 선점되면 다시 준비 상태가 되고, I/O를 요청하면 대기 상태로 이동한다. 기다리던 작업이 완료되면 다시 준비 상태로 돌아간다. ...

January 12, 2025

The Swift Programming Language. Concurrency (3)

Actors 태스크를 이용하여 프로그램을 분리된 동시성 조각으로 나눌 수 있다. 태스크는 서로 독립적이기 때문에 동시에 실행되어도 안전하다. 하지만 가끔씩 태스크들 사이에 정보를 공유해야 하는 경우가 있다. 액터는 동시성 코드 사이에 정보를 안전하게 공유하도록 해준다. 클래스처럼 액터는 레퍼런스 타입이다. 따라서 Classes Are Reference Types에서 값 타입과 레퍼런스 타입을 비교한 것이 액터에도 적용된다. 클래스와 다르게, 액터는 한번에 하나의 작업만 변경 가능한 상태(mutable state)에 접근하도록 허용하기 때문에, 여러 태스크가 액터의 한 인스턴스에 상호작용하는 것을 안전하게 해준다. 예를 들어 다음은 온도를 기록하는 액터이다. ...

June 26, 2023

The Swift Programming Language. Concurrency (2)

Asynchronous Sequences 이전 섹션의 listPhotos(inGallery:) 함수는 모든 배열의 원소들이 준비된 후, 비동기적으로 전체 배열을 리턴한다. 다른 접근 방법으로는 비동기 시퀀스(asynchronous Sequence) 를 사용하여 컬렉션의 요소 하나를 한 번에 하나씩 기다리는 것이다. 다음은 비동기 시퀀스를 반복하는 모습이다. import Foundation let handle = FileHandle.standardInput for try await line in handle.bytes.lines { print(line) } 일반적인 for-in 루프를 사용하는 대신에, 위의 예시는 for 다음에 await를 작성한다. 비동기 함수나 메소드를 호출할 때 처럼 await를 쓰는 것은 정지 가능한 지점을 나타낸다. for-await-in 루프는 각 반복이 시작될 때, 다음 원소가 준비될 때 까지 기다리는 동안 실행을 정지한다. ...

June 26, 2023

The Swift Programming Language. Concurrency (1)

Concurrency 스위프트는 구조화된 방식의 비동기적이고 병렬 수행되는 코드 작성에 대한 지원이 내장되어있다. 비동기(Asynchronuous) 코드는 일시중단 되었다가 나중에 재개할 수 있지만, 한번에 프로그램의 한 부분만 실행된다. 프로그램에서 코드를 중단하고 재개하면 네트워크에서 데이터를 불러오거나, 파일 파싱과 같은 긴 시간이 걸리는 작업을 계속 진행하면서 UI 업데이트와 같은 짧은 시간이 걸리는 작업을 계속할 수 있다. 병렬 코드(Parallel code) 는 동시에 실행되는 코드들을 의미한다 — 예를 들어 4코어 프로세서를 가진 컴퓨터는 각각의 코어가 코드 하나씩을 실행하게 하여, 네 개의 코드를 동시에 실행할 수 있다. 병렬과 비동기 코드를 사용하는 프로그램은 한번에 여러 작업을 수행하고, 외부 시스템을 기다리는 작업을 일시 중단한다. 이 챕터의 나머지 부분에서 용어 동시성(concurrency) 는 비동기 및 병렬 코드를 지칭한다. ...

June 23, 2023