nonisolated(unsafe)

👋 들어가기 전
이번에 학습해볼 내용은 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 |