iOS/swift

옵셔널*****/ 언랩핑***** / 값이 있는지 없는지 모른다?

글자줍기 2021. 12. 13. 16:08
반응형

옵셔널이란? 값이 있을수 있고 없을수도 있다.

  • 값이 있는지 없는지 그것을 알지 못하는 상태이다.
  • ?가 없다면 값이 있는 상태이다.
  • 값이 있을 수도, 없을 수도 있음을 표현
  • nil이 할당 될 수 있는지 없는지 표현

옵셔널이 왜 필요할까?

  • 추후 값이 들어오는 것에 따라서 유동적으로 처리하고 싶을때!
  • nil의 가능성을 명시적으로 표현한다.
  • 전달받은값이 옵셔널이 아니라면 nil체크를 하지 않더라도 안심하고 사용 
  • 예외 상황을 최소화하는 안전한 코딩

예를 들어, 네트워크 작업을 통해 데이터가 들어왔는지? 들어오지 않았는지? 를 우리는 장담할 수 없음

그럴때 데이터형을 옵셔널로 처리해놓고,

데이터가 존재한다면 -> 데이터에 맞게 처리하고

데이터가 존재하지 않는다면 (nil) -> 예외 구문 처리하고 유동적으로 후속 처리

https://i-colours-u.tistory.com/34?category=1000067

옵셔널은 언래핑이 필요하다.  언래핑방법은 1. 옵셔널바이딩  2. 강제언래핑이있다.

옵셔널 바인딩이란? nil체크를 하고 안전하게 값을 추출하는것이다.

언래핑방법
옵셔널 바인딩(nil체크를 하고 안전하게 값을 추출하는것이다.) 강제언래핑 (운이 좋게 값이 있으면 작동, nil값이면 강제종료)
 if let  
 guard let   

 

값이 있다.
값이 없다 -> nil   0은 값이 없는 상태가 아니다. 값이 0인 것
0 -> 다쓴 상태인 값

if myName ==  "" {

빈스트링인 입력되어 있는상태 , 이름을 입력해주세요라는 것은 맞지 않다. 

}

이름이 없는상태는 nil이다.


옵셔널을 벗겨내는것이 언랩핑이다.

coalesce  (a ?? 0) 의 뜻 = a의 값이 없으면 0을 넣어서 사용해라.

??   -> 값이 없으면 

강제추출은 값이 있다는 확신이 들때만 사용해라.. 없으면 앱이 죽어버림

 

✅  someVariable = nil

      let myValue = someVariable ?? 10 

      someVariable에 값이 없다면 기본값으로 10을 넣어주겠다. 


언랩핑이란? 옵셔널을 벗기는 상태

언래핑 되었다. 값이 있다는 뜻 

언래핑하는 법

✅  if let 

if let otherVariable = someVariable {

      print("값이 있다. otherVariable : \(otherVaraible)")

} else{

      print("값이 없다. ")

}

      if let 해주고, 값이 있다면 otherVariable에 넣어주겠다.

a라는 값이 있으면 언래핑해서 hasNumber에 담아라

https://www.inflearn.com/course/uikit-ios14/lecture/80730?tab=curriculum&volume=1.00&speed=1.25&quality=1080

 

✅  gurad let

클래스나, 펑션안에서 주로 사용, 실행하고 값이없으면 펑션바깥으로 나간다.

guard가 붙어 있으면, 값이 없으면 끝나버림 / 괄호바깥의 내용은 실행이 안됨 return 한다. 그냥 지나간다.

일부분을 실행하려면, if let을 사용, 전혀 사용하지 않으려면 guard let사용

(함수에서 반드시 실행되어야할 조건을 체크하고, 조건에 맞지 않는 경우 로직을 조기 종료하기 위한 용도로 사용)

 

https://www.youtube.com/watch?v=60VSuIY81iQ&list=PLgOlaPUIbynoqbQw_erl3L2w7vfOTCtFD&index=5 

 

1. 옵셔널이란??

  • 값이 있을 수도, 없을 수도 있음을 표현
  • nil이 할당 될 수 있는지 없는지 표현
// someOptionalParm에 nil이 할당 될 수 있다.
func someFunction(someOptionalParam: Int?) {
       // ....
}

/// someOptionalParm에 nil이 할당 될 수 없다.
func someFunction(someOptionalParam: Int) {
       // ....
}

someFunction(someOptionalParam: nil)
// someFunction(someParam: nil) 

 

2. 옵셔널 문법과 선언

  • 옵셔널 문법 = enum + generics (수업 후반에 다시 배울거에요)
  • 옵셔널 선언
enum Optional<Wrapped>: ExpressibleByNiliteral {
         case none
         case some(Wrapped)
}

let optionalValue: Optional<Int> = nil
let optionalValue: Int? =nil

 

  • 옵셔널 표현

          1. 느낌표(!)를 이용한 암시적 추출 옵셔널 

// Implicitly Unwrapped Optional
var implicitlyUnwrappedOptionalValue: Int! = 100

switch implicitlyUnwrappedOptionalValue {
case .none:
    print("This Optional variable is nil")
case .some(let value):
    print("Value is \(value)")
}

// 기존 변수처럼 사용 가능
implicitlyUnwrappedOptionalValue = implicitlyUnwrappedOptionalValue + 1

// nil 할당 가능
implicitlyUnwrappedOptionalValue = nil

// 잘못된 접근으로 인한 런타임 오류 발생
//implicitlyUnwrappedOptionalValue = implicitlyUnwrappedOptionalValue + 1

          2. 물음표(?)를 이용한 옵셔널

// Optional
// int 값이 들어 있을수도 있고, 없을수도 있는 변수다.
var optionalValue: Int? = 100

switch optionalValue {
case .none:
    print("This Optional variable is nil")
case .some(let value):
    print("Value is \(value)")
}

// nil 할당 가능
optionalValue = nil

// 기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이므로 연산불가
//optionalValue = optionalValue + 1

https://www.boostcourse.org/mo122/lecture/11240?isDesc=false 

 

:: 옵셔널 추출 :: 

 

1. 옵셔널 추출이란?

  • 옵셔널에 들어있는 값을 사용하기 위해 꺼내오는 것

 

2. 옵셔널 방식 (1.옵셔널 바인딩과  2.강제추출방법 )

  • 옵셔널 바인딩 - 상자에 물어본다 값이 있습니까??? 없습니까?? 똑똑 

1. nil 체크 + 안전한 추출
2. 옵셔널 안에 값이 들어있는지 확인하고 값이 있으면 값을 꺼내옵니다.
3. if-let 방식 사용

func printName(_ name: String) {
    print(name)
}

var myName: String? = nil

//printName(myName)
// 전달되는 값의 타입이 다르기 때문에 컴파일 오류발생

if let name: String = myName {
    printName(name)
} else {
    print("myName == nil")
}


var yourName: String! = nil

if let name: String = yourName {
    printName(name)
} else {
    print("yourName == nil")
}

// name 상수는 if-let 구문 내에서만 사용가능합니다
// 상수 사용범위를 벗어났기 때문에 컴파일 오류 발생
//printName(name)


// ,를 사용해 한 번에 여러 옵셔널을 바인딩 할 수 있습니다
// 모든 옵셔널에 값이 있을 때만 동작합니다
myName = "yagom"
yourName = nil

if let name = myName, let friend = yourName {
    print("\(name) and \(friend)")
}
// yourName이 nil이기 때문에 실행되지 않습니다
yourName = "hana"

if let name = myName, let friend = yourName {
    print("\(name) and \(friend)")
}
// yagom and hana
  • 강체추출 : 옵셔널에 값이 들어있는지 아닌지 확인하지 않고 강제로 값을 꺼내는 방식,
  • 값이 있다는 확신이 들때만 사용해라.. 없으면 앱이 죽어버림
  • 만약 값이 없을경우(nil) 런타임 오류가 발생하기 때문에 추천되지 않습니다.
var myName: String? = yagom
var youName: String! = nil


printName(myName!) // yagom
myName = nil

//print(myName!)
// 강제추출시 값이 없으므로 런타임 오류 발생
yourName = nil

//printName(yourName)
// nil 값이 전달되기 때문에 런타임 오류발생

 

 

 

반응형