iOS/Swift Concurrency

nonisolated(unsafe)

Hamp 2025. 5. 19. 22:42
반응형

👋 들어가기 전

이번에 학습해볼 내용은 nonisolated(unsafe) 키워드다.

이전에 actor 포스티에서 nonisolated 키워드는 알아봤다.

 

간단히 정리하면 현재 격리 주체인 actor안에 코드가 있지만

actor의 격리 범위를 벗어나고 싶을 때 사용하는 키워드였다.

🏁 학습할 내용

  • unsafe의미
  • 위험한 형태가 왜 존재할까?
  • 어디에 쓸까?

🦺 unsafe가 왜 붙었을까?

여기서 하나 짚고 넘어갸야되는 것은 nonisolated 키워드는 격리 범위를 벗어난다는 의미하는 것

즉, 외부에서 접근하는 형태로 사용한다는 것이다.

 

이게 컴파일 타임에 격리 상태 체크를 무시한다는 것이 아니다.

즉, 외부처럼 접근할 것이면 async / await으로 잠재적 중단 포인트를 만들어놔야한다.

 

여기서 unsafe는 컴파일 타임에 동시성관련 격리/ 동기화 메커니즘을 무시하겠다.


☢️ 위험한 형태가 왜 존재할까?

 

사용목적은 아직 정확히는 찾지 못해서 GPT 도움을 좀 받았다.

 

간단히 정리하면 읽기 전용일 때, 사용하면 퍼포먼스 최적화를 할 수도 있다? 라는 결론이 나온다.

⛏️ 퍼포먼스 최적화

actor는 내부 상태 보호를 위해 동기화를 수행하는데, 이게 비용이 큽니다.

만약 특정 메서드가 actor의 상태를 참조하긴 하지만 실제로는 동기화가 필요 없는 경우
(ex. 읽기만 하고 경쟁 조건이 없는 경우)

 

이럴 때 nonisolated(unsafe)를 사용하면 동기화 비용을 피하면서 퍼포먼스를 극대화할 수 있습니다.

 

✅ 컴파일 타임에 완벽한 체크를 할 자신이 있다면

내가 현재 구현하고 있는 내용이 @unchecked Sendable이 필요하고

영향을 받는 도메인 범위에서 동시성 문제 해결 로직이 자신이 있다면, 사용해볼 수 는있다.


❓ 어디에 쓸까?

unsafe는 정말 정말 정말 Data-race가 일어나지 않을 때 쓴면 될 듯하고

nonisolated는 엑터 외부처럼 접근하고 싶을 때 쓰는 것 ..

 

그러면 그냥 전역변수로 let 쓰면 되는거 아님?

 

let은 unsafe 쓰는 조건이 맞다, 하지만 전역변수는 기본적으로 MainActor에 격리되어있다.

AppDelegate에 hello 변수를 마들어보니 암묵적으로 @MainActor에 격리되어있다.

 

이유는 UIResponder와 UIApplicationDelegate가 @MainActor 격리를 검사하고 있기 때문이다.

 

위험히니 정말 필요할 때 아니면 사용을 지양하자!


😀 소감 및 마무리

키워드 nonisolated nonisolated(unsafe)
대상 함수 전역 변수
actor 내부 격리 사용 메커니즘 이용 X X
컴파일 타임 검사 여부 O X

반응형