[문제해결] @Sendable과 isolated 실전 응용: AVCaptureDevice.requestAccess(for:)

2025. 3. 15. 17:57·📱 iOS/Swift Concurrency

문제해결

final class CustomAlbumViewController: UIViewController {
    private func checkCameraAuthorization() {
        let authorization = AVCaptureDevice.authorizationStatus(for: .video)

        switch authorization {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { @Sendable granted in
                if granted {
                    Task { [weak self] in
                        await self?.openCamera()
                    }
                }
            }
            ...
        }
    }

    private func openCamera() {
                // 대충 카메라 화면 띄우기..
    }
}

위 코드에서 @Sendable을 붙이지 않으면 Thread 16: EXC_BREAKPOINT (code=1, subcode=0x105a80214)

잘못된 접근에 대한 에러가 발생한다.

추가로 openCamera()는 동기 메소드인데, @Sendable이 있으면 await를 붙여야 한다.

@.Sendable이 없으면 왜 위처럼 에러가 발생할까 ?

그리고 또 하나, 동기 메소드를 실행하더라도 @.Sendable 클로저 내라면 왜 await를 붙여야할까 ?


해결과정

AVCaptureDevice.requestAccess(for: .video) 정의 살펴보기

해당 AVCaptureDevice.requestAccess(for: .video) 에 정의를 보면 다음과 같이 돼 있다.

그리고 살짝 위로 올리면

    The completion handler is called on an arbitrary dispatch queue. It is the client's responsibility to ensure that any UIKit-related updates are called on the main queue or main thread as a result.

번역하면 다음과 같음

완료 핸들러는 임의의 디스패치 큐에서 호출됩니다. UIKit 관련 업데이트가 결과적으로 메인 큐 또는 메인 스레드에서 호출되도록 하는 것은 클라이언트의 책임입니다.

즉, 컴플리션 핸들러가 다른 백그라운드 메소드에서 돌 테고, UI 관련 작업할 거면 니가 알아서 메인 스레드에서 돌려라.

따라서 @Sendable이 없으면 에러가 발생했던 이유가 해당 클로저가 다른 스레드에서 돌 수 있게끔 안정성을 보장하기 위해 @Sendable을 붙여줘야 했다.

 

동기 메소드에 await를 해줘야 하는 이유

또한, openCamera() 메소드는 동기 메소드이다.

그리고 뷰컨트롤러에 존재하는 메소드이다.

뷰컨트롤러는 @MainActor가 선언되어 있어서 openCamera() 메소드는 메인액터에 격리되어 있다.

@Sendable에 의해 백그라운드 스레드에서 openCamera를 실행시킬 수도 있다는 말인 즉슨, 메인액터에 격리된 메소드를 실행하기 위해서는 await를 붙여서 호출해야 한다는 것이다.

왜냐하면 액터에 격리된 것의 경우 하나의 액터만 접근할 수 있기 때문이다.

Swift 동시성 시스템에서 액터 간 전환은 항상 await를 요구하니까


배운 점

  1. 컴플리션 핸들러가 백그라운드 스레드에서 도는 거기 때문에 @Sendable이 필요한 거다.
    즉, @Sendable을 붙이지 않으면 백그라운드 스레드에서 동작 시 잘못된 접근 에러가 발생할 수 있다.
  2. @Sendable을 준수하는 클로저까지 왔다면, openCamera() 메소드는 await로 실행되어야 한다.
    왜냐하면 MainActor(뷰컨메소드)에 isolated 격리되어 있기 때문에 하나의 개체만 실행할 수 있으므로 await를 붙여서 하나의 액터만 해당 메소드를 사용할 수 있게 한다.
    동기 메소드라 await가 필요없지만, 메인액터에 격리되어 있기 때문에 await를 붙여야 하는 것.

 


레퍼런스

https://developer.apple.com/forums/thread/764777?answerId=807248022#807248022

 

Request authorization for the noti… | Apple Developer Forums

I presume that getNotificationSettings() is a method on an main-actor-isolated type, like your app delegate. If it isn’t, you don’t get this error. If so, the easiest fix is to mark getNotificationSettings() as nonisolated. Share and Enjoy — Quinn

developer.apple.com

 

 

 

저작자표시 (새창열림)

'📱 iOS > Swift Concurrency' 카테고리의 다른 글

[Swift Concurrency 11편] Main Actor  (0) 2025.02.26
[Swift Concurrency 10편] Actor는 한글 키보드로 'ㅁㅊ색' 이란 걸 아시나요?  (0) 2025.02.26
[Swift Concurrency 9편] Sendable 프로토콜  (0) 2025.02.26
[Swift Concurrency 8편] Task와 구조화된 동시성(= Structed Concurrency)  (0) 2025.02.26
[Swift Concurrency 7편] 비동기 호출에서의 스레드 제어권  (0) 2025.02.26
'📱 iOS/Swift Concurrency' 카테고리의 다른 글
  • [Swift Concurrency 11편] Main Actor
  • [Swift Concurrency 10편] Actor는 한글 키보드로 'ㅁㅊ색' 이란 걸 아시나요?
  • [Swift Concurrency 9편] Sendable 프로토콜
  • [Swift Concurrency 8편] Task와 구조화된 동시성(= Structed Concurrency)
kyxxn
kyxxn
컴퓨터공학을 좋아하는 대학생의 공부 일기
  • kyxxn
    컴공 학부생의 공부 일기
    kyxxn
  • 전체
    오늘
    어제
    • 분류 전체보기 (156)
      • 📱 iOS (64)
        • Xcode (10)
        • Swift (17)
        • Swift Concurrency (12)
        • UIKit (21)
        • SwiftUI (0)
      • 🖥️ Computer Science (57)
        • 🏛️ Software Architecture Pa.. (2)
        • 👨🏻‍🎨 Design Pattern (3)
        • Data Structure (4)
        • Algorithm (10)
        • Computer Architecture (4)
        • Operating System (19)
        • Network (15)
      • ✍🏻 회고록 (9)
      • 🎸 기타 (25)
        • 해커톤 (1)
        • git (6)
        • 세미나 (1)
        • 책을 읽고 (1)
        • AOS, Kotlin (6)
        • Reinforcement Learning (9)
  • 블로그 메뉴

    • 링크

      • 깃허브
      • 일상 블로그
    • 공지사항

    • 인기 글

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.0
    kyxxn
    [문제해결] @Sendable과 isolated 실전 응용: AVCaptureDevice.requestAccess(for:)
    상단으로

    티스토리툴바