Swift: region based isolation

틀틀보·2025년 12월 22일

Swift Concurency

목록 보기
7/11
post-thumbnail

Swift의 동시성(actors, async/await)에서 값이 어느 격리 영역(region)에 속해 있는지 추적해서, 서로 다른 격리 영역 간에 안전하지 않은 공유/전달이 있는지 검사하는 기능

기존의 동시성 모델

  • Sendable을 준수하지 않으면 객체를 다른 Taskactor로 이동 불가

  • 엄격한 관리로 개발자 입장에서 까다로운 코드 작성

region-based-isolation

동작 방식

객체가 생성된 영역에서 벗어나 다른 영역으로 전달 된 후, 기존 영역에서 다시 사용되지 않음이 보장되면 Sendable을 준수하지 않더라도 전달 가능

struct ClientManager {
    let service: ClientProcessingService
    
    func startConfiguration() async {
        let newClient = NonSendableClient(name: "NewUser")
        
        // 'newClient'는 NonSendable이지만, 아래 Task로 전달된 후 
        // 생성된 영역에서 다시 사용되지 않으므로 안전하다고 판단합니다.
        await Task {
            await service.processRemote(client: newClient)
        }.value
        
        // 만약 여기서 print(newClient.name)을 호출하면 컴파일 에러가 발생
        // Task로 전달된 객체를 다시 사용할 수 X
    }
}
func example1() {
    let a = NonSendable()      // region R1 = { a }
    let b = a                  // b는 a와 alias 가능 → R1 = { a, b }

    var c = NonSendable()      // region R2 = { c }

    c = b                      // 이제 c도 a/b와 같은 인스턴스를 가리킬 수 있음
                               // → R1 = { a, b, c }, R2는 사라지고 R1로 병합
}
  • 컴파일러는 함수 안의 값들에 격리 정보를 태그처럼 붙이고, 전달 관계를 따라 서로 얽힌 값들을 같은 region으로 그룹화

  • 그룹화 진행 중에 region이 2개 이상의 isolation-domain에 연결되면 동시성 문제 가능성으로 판단하고 에러 발생

@MainActor
final class ViewModel {
    var ns: NonSendable?
}

final class NonSendable {
    var value = 0
}

func overlapExample(vm: ViewModel) async {
    // 메인 actor에서 NonSendable을 만든다고 가정
    vm.ns = NonSendable()
    // 여기서 vm.ns가 속한 region은 @MainActor에 붙어 있음
    //   Regions (개념상): [{(vm, vm.ns), @MainActor}]

    // 다른 task에서 이 값을 잡아감
    Task {
        // 이 클로저는 기본적으로 task‑isolated
        let local = vm.ns      // 메인 actor 값이 task 쪽으로 흘러옴
        local?.value += 1
    }
}
  • vm.nsmain Actor domaintask domain에서 동시에 접근되면 vm.ns가 속한 region이 두 domain에 있게 됨.

  • 컴파일러가 2개 이상의 domain에 같은 region이 있음을 판단하고 에러

사용됨으로써 생기는 이점

  • 컴파일러가 각 객체의 동시성을 추적함으로써 컴파일 시간에 동시성 문제 조기 발견 가능

  • 기존 안전한 코드에서 생기던 에러를 줄일 수 있음. (컴파일러가 더욱 코드 흐름을 이해하고 있기 때문)

참고
https://github.com/swiftlang/swift-evolution/blob/main/proposals/0414-region-based-isolation.md

https://priorart.substack.com/p/swifts-region-based-isolation-log

profile
안녕하세요! iOS 개발자입니다!

0개의 댓글