Swift 둘러보기 (A Swift Tour) - 동시성 (Concurrency)

00yhsp·2024년 3월 26일

비동기적으로 실행되는 함수를 나타내기 위해 async를 사용한다.

func fetchUserID(from server: String) async -> Int {
	if server == "primary" {
    	return 97
    }
    return 501
}

앞에 await를 작성하여 비동기 함수를 호출하는 것을 나타낸다.

func fetchUsername(from server: String) async -> String {
	let userID = await fetchUserID(from: server)
    if userID == 501 {
    	return "John Appleseed"
    }
    return "Guest"
}

비동기 함수를 호출하기 위해 async let을 사용하여 다른 비동기 코드와 병렬로 실행할 수 있다.
await를 작성하여 반환된 값을 사용한다.

func connectUser(to server: String) async {
	async let userID = fetchUserID(from: server)
    async let username = fetchUsername(from: server)
    let greeting = await "Hello \(username), user ID \(userID)"
    print(greeting)
}

비동기 함수의 반환을 기다리지 않고 동기 코드에서 비동기 함수를 호출하려면 Task를 사용한다.

Task {
	await connectUser(to: "primary")
}
// Prints "Hello Guest, user ID 97"

동시성 코드를 구성하기 위해 작업 그룹(task group)을 사용한다.

let userIDs = await withTaskGroup(of: Int.self) { group in
	for server in ["primary", "secondary", "development"] {
    	group.addTask {
        	return await fetchUserID(from: server)
        }
    }
    
    var result: [Int] = []
    for await result in group {
    	result.append(result)
    }
    return results
}

액터는 다양한 비동기 함수가 동시에 동일한 액터의 인스턴스와 안전하게 상호작용할 수 있다는 것을 제외하고는 클래스와 유사하다.

actor ServerConnection {
	var server: String = "primary"
    private var activeUsers: [Int] = []
    func connect() async -> Int {
    	let userID = await fetchUserID(from: server)
        activeUsers.append(userID)
        return userID
    }
}

액터의 메소드를 호출하거나 프로퍼티에 접근할 때,
액터에서 이미 실행 중인 다른 코드가 완료될 때까지 기다리고 있는 것을 나타내기 위해 코드에 await를 표기한다.

let server = ServerConnection()
let userID = await server.connect()
profile
iOS Dev

0개의 댓글