일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- concurrency
- Mac
- Object Capture
- AR Quick Look
- Hand Action Detect
- CoreML
- NSUserActivity
- AVFoundation
- MDM
- actor
- SF Symbols 3.0
- detent
- AppleEvent
- App Clip
- User Enrollment
- async
- WWDC 2021
- SWiFT
- ProRAW
- DriverKit
- Xcode Organizer
- swiftUI
- Physical Audio
- profile
- SF Symbols
- Hand Pose Detect
- METAL
- DooC
- Reality Composer
- Xcode Cloud
- Today
- Total
nyancoder
WWDC 2021 - Protect mutable state with Swift actors 본문
원본 영상: https://developer.apple.com/videos/play/wwdc2021/10133/
이 장에서는 Swift에서 새로 지원되는 Actor의 필요성과 활용에 대해서 알아봅니다.
기존 방식의 문제점
둘 이상의 스레드에서 동일 데이터에 접근할 때, 동시성 안정성이 보장되지 않아 예상하지 못한 결과를 얻을 수 있습니다.
기존에 이러한 문제를 컴파일 단계에서 회피하기 위한 수단으로 value타입을 사용하는 방법도 있습니다.
이 이외에 여러 스레드에서 동시에 접근되어야 하는 데이터가 손상되지 않도록 하기 위해서 아래의 방법을 사용할 수 있지만, 컴파일 단계에서 검증하는데 어려움이 있는 경우가 있었습니다.
- Atomic
- Lock
- Serial dispatch queues
Actor
- Actor는 class나 struct, enum 들과 같은 하나의 새로운 타입입니다.
- Actor내의 함수 호출은 모두 동기 호출이므로 중간에 다른 함수 호출이 끼어들 수 없습니다.
- 외부에서의 함수 호출은 비동기 호출로 이루어지며, async 키워드를 통한 비동기 처리와 마찬가지로 함수 호출의 결과를 받아 순서대로 처리하기 위해서 await 키워드를 사용할 수 있습니다.
Actor reentrancy
위의 예제에서 Actor 내의 image(from:) 함수에서 downloadImage(from:) 함수를 호출했을 때 현재 actor에서 수행 중인 작업은 일시정지가 됩니다. 그렇기 때문에 downloadImage(from:)의 결과를 받을 때까지 다른 작업이 동일 함수를 호출하여 cache의 상태를 변경할 수 있습니다. 위의 예제에서는 동일 url을 연속으로 두 번 호출한 경우, 두 번째 작업이 첫 번째 다운로드 작업이 끝나기 전에 실행되어 cache의 결과를 참조하지 않고 다운로드를 두 번 수행할 수 있습니다.
따라서 아래의 항목들을 유의해서 Actor를 다루어야 합니다.
- Actor내에서의 상태 변경은 동기화되어 이루어집니다.
- 하지만 Actor내의 한 작업의 실행이 일시 정지된 동안 다른 작업이 상태를 변경할 수 있습니다.
- 때문에 await 구문 이후에서는 변수의 값이 예상대로인지 확인을 해야 할 필요가 있습니다.
Actor isolate
- 변수의 접근은 항상 actor를 통해 이루어지는 것이 보장됩니다.
- 변수의 접근이 하나의 스레드에서 접근되는 것이 보장됩니다.
- nonisolated 키워드를 통해 특정 함수는 Actor의 내에 선언되어 있어도 Actor의 밖에서 선언된 것처럼 다룰 수 있습니다. 이런 경우 Actor의 상수에는 접근이 가능하지만 변수에 접근하는 경우 오류가 발생할 수 있습니다.
- Actor내부의 상태를 변경할 수 있는 객체를 리턴하는 것을 막기 위해서, Sendable 프로토콜을 통해 Actor의 내부의 값이 전달됩니다.
Sendable
- 동시성을 보장해주기 위해서 각 Actor의 외부로 전달할 수 있는 값은 Sendable 조건을 만족시켜야 합니다.
- 값 타입, Actor, 불변 클래스, 내부적으로 동기화 처리가 된 클래스, @Sendable 함수 타입이 이에 해당됩니다.
- @Sendable Closure는 변수를 캡처할 수 없으며, Sendable을 만족하는 값 만을 가질 수 있습니다.
- @Sendable은 Actor내의 함수를 동기로 실행할 수 없습니다.
Main actor
기존에 사용하던 DispatchQueue.main.async 함수를 호출하던 방식 대신 함수 앞에 @MainActor를 추가하여 함수가 메인 스레드에서 실행되도록 보장할 수 있습니다.
타입에도 @MainActor를 붙일 수 있으며, 해당 타입 내의 모든 함수와 속성은 MainActor의 것이 됩니다.
다른 Actor와 마찬가지로 원하지 않는 함수는 nonisolated 키워드를 붙여 Actor외부의 함수처럼 사용할 수 있습니다.
'WWDC > WWDC 2021' 카테고리의 다른 글
WWDC 2021 - Meet AsyncSequence (0) | 2021.07.01 |
---|---|
WWDC 2021 - Swift concurrency: Behind the scenes (1) | 2021.07.01 |
WWDC 2021 - Meet async/await in Swift (0) | 2021.06.30 |
WWDC 2021 - Explore structured concurrency in Swift iOS, macOS, tvOS, watchOS (0) | 2021.06.26 |
WWDC 2021 정리글 목차 (0) | 2021.06.26 |