본문 바로가기
📱Mobile/🔥Swift

[Swift] Optional 개념정리 (변수뒤에 !와 ?) optional 예제

by 후누스 토르발즈 2020. 12. 16.
반응형

Optional 개념정리

선택적인 이라는 뜻을가진 optional 은 swift에서 무엇일까요?

 

만약 치킨을 배달시키는 상황을 생각해볼까요?

일단 읽어볼게요!

 

  1. 배달어플에서 XCODE라는 치킨 가게를 클릭하고 치킨 메뉴를 선택합니다. [코드작성중]
  2. 아직은 맛 옵션을 고르지 않은 상태여서 맛은 최소 1개를 골라주세요! 라는 경고문구가 보입니다! [nil 경고]
  3. 하지만 맛 옵션을 고르지 않아도 주문은 가능하게 되어있습니다. 만약 맛옵션을 고르지 않으면 가게에서는 어떤 맛으로 줄까?
  4. 호기심에 아무맛도 고르지 않고 주문을 하게 됩니다. [nil 경고를 보았지만 실행]
  5. 주문서가 가게로 전달됩니다. [컴파일]
  6. 가게는 주문을 받았고 주문서를 읽고 순서대로 조리를 합니다. [Application 실행됨]
  7. 순서대로 조리하던 도중 방금 주문받은 치킨을 이제 조리할 차례입니다. 맛 옵션(var source:String?)을 확인해보니(source! 언래핑) nil 이었습니다. [무시했던 못한 nil을 발견]
  8. var source = 후라이드 또는 양념이어야 되는데 nil 이여서 후라이드를 하지도, 양념을 하지도 못하는 상황이 되버렸습니다.
  9. 가게에서는 "맛이 nil 이여서 주문 취소하였습니다..!" 라고 적어서 주문을 취소합니다. [에러 로그]
  10. 손님은 취소 알림을 받습니다. [Application 종료]

 

 

위에서 처럼 애플리케이션을 실행하는데 만일 예기치 않게 nil을 발견한다면 문제가 발생할 수도 있기때문에

xcode에서는 이런일이 없도록 코드를 작성하도록 도와줍니다

 

optional은 안정장치같은 역할을 해주는 것이죠! 문제가 발생하기전까지, 또는 문제가 발생하지 않는다면 '?'옵션이 되어 있다면 문제로 보지 않게되는 것이죠!

var source:String? = nil 이라면 메모리를 차지하는 상자를 만들어 두되 '!' 망치로 깨부시기전까진 안의 값을 모르니까 문제로 삼지 않습니다!!

만일 source! 한다면 그때서야 그안의 값을 볼수있게 됩니다.

 

만일 nil이 아닌 후라이드나 양념으로 확실히 선택해서 주문을 해주면 가게에서 주문을 취소하는 일이 없겠죠?

 

밑의 sample optional 소스를 보겠습니다.

import SwiftUI

struct ContentView: View {
    @State var nilValue:String? = nil
    var body: some View {
        Button(action: {
            active()
        }){
            Text("실행")
        }
    }
    
    func active(){
        //? 를 사용하는것은 안전장치를 붙이는것이다.
        //! 를 사용하는것은 언래핑하는것이므로 안전장치를 해제하는것이다.
        //var nilValue:String? = nil 로 옵셔널 설정
        print("nilValue : ", nilValue)
        //nilValue : nil 이 출력된다.
        //현재 값이 nil이기 때문에 실행시 nil이 출력된다. 하지만 xcode에서 경고를 표시하고 있기 때문에 옵셔널이 설정되어있는데
        //값이 nil 일수도 있는데 타입을 바꾸지 않겠냐는 질문을 던져준다.
        //이런 경고를 없애는 방법으로는
        
        //1 :: 만약 값이 nil이라면 값을 대체한다.
        print("nilValue : ", nilValue ?? "nil인 경우에 들어갈 대체 text")
        
        //2 :: Any Type인데 경고를 띄우지 않는것을 보면 Any Type은 nil 값이 들어오는 것을 문제로 삼지않는것으로 보인다.
        print("nilValue : ", nilValue as Any)
        
        //3 :: ! 를 사용하여 옵셔널 해제 ( 언래핑 )
        print("nilValue! : ", nilValue!) // 사용시 에러발생.
        // nilValue의 값이 nil이 아니라면 에러가 발생하지 않는다.
        //실행하게되면 "치명적인 오류 : 옵션 값을 언 래핑하는 동안 예기치 않게 nil이 발견되었습니다" 가 출력된면서 종료된다.
        //이유라면 개발자는 알았을지언정 xcode 입장에서는 예기치 않게 갑작스럽게 nil을 마주하게 되었다는 것이다.
        //xcode는 보다 완벽한 버그없는 애플리케이션을 만들수 있도록 도와준다.
        
        //이번에는 위 3가지의 경우와는 조금 다르게 if, guard를 사용한 언래핑 방법을 사용하여보겠다.
        //현재 nilValue의 값은 여전히 nil 이다.
        //4 :: if 로 값이 있다면 안의 코드를 실행하고 다음코드를 실행한다.
        print("\n::::::::::::::::   if 와 guard  ::::::::::::::::\n")
//        nilValue = "NOT nil" // 주석 풀어서 실행하여본다
        print("1구간")
        if let result1 = nilValue {
            print("2구간 / nil이 아니면 실행")
            print("nil이 아니면 실행")
            print("result1 : ", result1)
            //result1 값에 접근 가능
        }
        print("3구간")
        //5 :: guard 를 이용하여 else 인 경우 return 을 강제한다.
        guard let result2 = nilValue else {
            print("4구간 / nil이면 실행")
            //result2 값에 접근 불가.
            return
        }
        print("result2 : ", result2)
        print("5구간")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

nil 배제 권유 경고
예기치못한 nil을 발견할시

 

여기서 중요한것은 만일 '!'을 남발하는 경우 어플리케이션이 종료되는 일이 매우 많아질 수 있고 개발자가 그 모든것을 알고있지는 못 할것 이라는 것입니다!

 

개인적인 생각으로는 !의 사용을 줄이고 if 또는 guard의 사용을 많이하는것이 좋아보입니다.

 

 

참고 : zeddios.tistory.com/16

반응형