Swift

❓ Implicitly Unwrapped Optional

_yunie 2024. 7. 1. 13:30

안녕하세요!

벌써 7월이 다가왔네요..! 이제 본격적인 장마시작인데, 길 다니실 때 항상 조심하시고요!

그럼 7월도 따끈따끈한 글로 시작해 볼까요~!!

 

 

❓Implicitly Unwrapped Optional (IUO)

오늘은 줄여서 IUO라고 불리는 암묵적 옵셔널 추출에 대해 알아보려고 합니다

이전에 옵셔널은 값이 있을 수도, 없을 수도 있는 변수/상수를 선언할 때 사용해 준다고 했죠?

그리고 그 옵셔널을 해제하기 위해 Forced Unwrapping, Optional Binding의 방식을 사용하게 된다고 말씀드렸습니다

 

그런데 이 IUO라는 친구는 특별한 형태의 옵셔널로 옵셔널로 선언한 변수/상수임에도 불구하고 값을 꺼내올 때 자동으로 옵셔널을 해제해 준다는 특징을 가지고 있습니다

 

이제 예제로 한 번 살펴볼게요

혹시 이전에 옵셔널을 선언했던 방식이 기억나시나요?

다음과 같이 옵셔널은 ? 로 선언해 줬었죠

var optionalString1: String? = "this is value"

 

반면, IUO는 마치 Forced Unwrapping처럼 ! 를 이용해서 변수/상수를 선언해 주게 됩니다

var iuoString: String! = "this is value"

 

둘의 차이라면 IUO는 선언해주고자 하는 데이터 타입에 !를, Forced Unwrapping은 열어보고자 하는 옵셔널 데이터에 !를 붙여준다는 점입니다 (그러니까 헷갈리시면 안 돼요!)

 

이제 이렇게 선언한 변수를 불러와볼게요

그럼 생각한 결과랑 조금 다르게 출력되는 것을 확인할 수 있습니다 

 

엥? 분명 옵셔널을 자동으로 해제해 준다고 했는데 왜 여전히 옵셔널이죠..?

 

사실 IUO가 옵셔널을 자동으로 해제해 준다는 것도 특정한 조건을 충족할 때에만 가능합니다 

 

자, 위에서 선언한 optionalString과 iuoString을 각각 Type Annotation으로 선언된 새로운 변수에 담아볼게요

 

그럼 일반적인 옵셔널 타입에서는 에러가 발생합니다❗️

하지만 IUO를 사용해 준 변수는 아무런 에러가 발생하지 않죠

 

그리고 이 상황에서 iuo를 출력해 주게 되면...

 

바로 우리가 생각하던 값이 튀어나오게 됩니다!

 

 

🧐 왜 이런 결과가 나오는 걸까요?

먼저 옵셔널 타입에서 왜 오류가 났는지부터 생각해 보면 이유는 사실 단순하죠

저희가 옵셔널이라는 상자를 열어주지 않고 무작정 그 안의 값을 넣으려고 했으니까요

그렇기 때문에 Optional Binding을 통해 옵셔널을 해제해 줬다면 아무런 오류 없이 값을 넣을 수 있었을 겁니다

 

그럼 IUO는..?

IUO는 방금처럼 Optional Type을 Non-Optional Type에 대입할 때, 따로 옵셔널을 해제하는 과정을 거치지 않고 대입할 수 있게 만들어줍니다 

그래서 저희가 처음에 봤던 개념처럼 자동으로 옵셔널을 해제해 준 겁니다

 

이런 결과를 보면 당연히 IUO가 편리해서 좋은 거 아니야?라는 생각이 드실 겁니다

하지만 아닙니다!

 

 

❗️ IUO = Forced Unwrapping

IUO도 결국 Forced Unwrapping과 같은 형태로 동작합니다

var iuoString: String! = nil
var iuo: String = iuoString
print(iuo)

 

그래서 만약에 iouString에 nil을 넣어주고 iou에 다시 값을 대입해주려고 하면..

 

iouString이라는 값 nil인데? 하고 에러가 나게 됩니다 

앱에서는 런타임 에러를 일으킬 거고요 

 

Optional Binding에 비해 편한 건가 했더니 그것도 아니고 Forced Unwrapping이랑 동작방식도 같으면 얘는 왜 쓰는 거..?

 

저도 처음에 이런 생각이 들어서 정말 궁금했는데요..!

생각보다 가까운 곳에 예시가 있었습니다!😆

 

 

🧐 IUO는 언제 사용될까요?

 

스토리보드를 사용해 보신 분이라면 모를 리가 없는 IBOutlet에서 IUO를 적용하고 있습니다!

 

만약 각 컴포넌트에 IUO를 적용하지 않고 옵셔널을 사용했다면 아마 Label에 텍스트를 넣어주고 색을 바꿔주고 할 때마다 Optional Binding과정을 거쳐야 할 겁니다 

하지만 한 번이라도 사용하게 된다면 그때 초기화가 일어나게 되고 뭐든 값을 가지게 되는 상태가 되기 때문에 굳이 사용할 때마다 Optional Binding을 해주는 건 아무래도 불편할겁니다 (상상만 해도..😮‍💨)

그래서 IUO를 통해 지금은 값이 없지만 나중에는 값이 있을 거야 그러니까 옵셔널을 자동으로 해제해줘 하고 알려주는거죠

 

이처럼 IUO는 프로퍼티의 초기화가 이후에 이루어지는 경우(프로퍼티 지연 초기화)에 사용됩니다 

 

이외에는 Swift가 Obj-C API와 상호작용 시, Obj-C의 nil을 반환할 가능성이 있는 메서드나 프로퍼티를 Swift에서 사용하려고 할 때 사용됩니다

Obj-C에는 Swfit의 옵셔널이라는 개념의 타입이 따로 없기 때문에 Swift로 받아올 때 IUO로 처리하는 경우가 있다고 합니다 

 

이렇게 경우만 놓고 봐도 직접 사용할 일은 거의 없어 보이죠..?

그러니까 되도록 안전한 Optional Binding을 사용하는 게 좋겠습니다! 

 

 

✏️ 오늘의 요약

  • IUO(옵셔널 암시적 추출)
    • 선언해 주고자 하는 데이터타입에! 사용
    • Non-Optional Type에 Optional Type을 대입할 때 자동으로 옵셔널을 해제해 줌
    • 강제 원래핑이랑 동일하기 때문에 nil이라면 에러 발생
    • 프로퍼티 지연 초기화 시 사용
    • Obj-C API와의 상호 작용 시 사용 

 

 

📚 참고

https://zeromin-code.tistory.com/157

https://longlivedrgn-miro.tistory.com/58

https://yunie-studylog.tistory.com/manage/posts/

 

'Swift' 카테고리의 다른 글

❓ Optional Chaining  (0) 2024.07.05
❓Nil Coalescing (??)  (0) 2024.07.03
❓ Optional Binding  (0) 2024.06.28
❓ Forced Unwrapping  (0) 2024.06.26
❓ Optional  (0) 2024.06.24