iOS | Optinal에 대한 발표 준비/ 자료정리

유재우·2022년 1월 25일
0

Optional 발표준비

  • 이번 iOS 앱 개발자 워크숍에서 iOS관련 발표를 준비하게 되었는데
    주제는 iOS 앱 개발에서 중요한 Optional에 대해 발표하기로 정했다.

Optional의 사전적 의미

Optional : 선택적인
  • 한마디로 Swift문법 상에서 값이 있을 수도 있고 없을 수도 있다는 뜻이다.
문자열로 예를 들자면
"Swift" -> 값이 있다.
""      -> 값이 없다??
"" 는 값이 없는게 아닌 빈 문자열이다.
문자열에서 값이 없다 -> nil
---------------------------------------------------
정수형에서도 똑같다.
12  -> 값이 있다.
0   -> 이 또한 값이 0이다.
nil -> 값이 없다.
딕셔너리와 배열또한 비어있다고 값이 없는 것이 아닌 비어있는 배열,딕셔너리일 뿐이고 값이 없다는 nil이다.

nil

  • 값이 없다. 라는 뜻
  • 모든 변수에 사용할 수 있는것은 아니다.
1)
var test: String = “테스트입니다”
test = nil // 오류
---------------------------------------
2)
var opt: String?
print(opt) // nil
---------------------------------------
3)
var good: String? = "정상 작동"
print(good) // 정상 작동
---------------------------------------
4)
let error: String = error
print(error) // 오류

이 4가지 예제에는 무슨 차이가 있을까?

1) 
test 변수에 이미 "테스트입니다"라는 값을 가지고 있는데 이 문자열을 비울순 있어도 
값이 없는 nil로 바꿀순 없다.
2)
변수 opt에 아무 값도 지정하지 않았을 때 ?를 붙여 Optional형으로 사용이 가능하다.
이 형태가 대표적인 Optional형이다.
3)
2번과 같이 String뒤에 ?를 붙여서 Optional형으로 지정했지만 값이 있다.
이 처럼 Optional이 꼭 값이 없는 것만을 지칭하는게 아니다.
4)
String형으로 상수를 선언했지만 값이 문자형이 아니기 때문에 컴파일 오류가 난다.

Optional이란?

  • Optional이란 앞서 살펴 보았던 예제들과 설명에서 보았듯이 값이 있을수도 없을수도 있는 변수 혹은 상수를 뜻한다.
  • Optional에 초기 값을 지정하지 않는다면 기본 값(Default Value)은 nil이다.
var test: String? 
print(test) // nil
----------------------
let ex: Int? = 1
print(ex) // 1
var opt: String? 
print(opt) // nil
opt = “Optional”
print(opt) // Optional(“Optional”) 값이 Optional형태로 감싸져서 출력

표로 보면 그 구성을 더 이해하기가 쉽다.

          ⌈----> nil (값이 없음을 뜻함)
Optional  |
          ⌊----> 어떠한 값(String, Int, ...,)

Optional Binding(옵셔널 바인딩)이란?

  • 옵셔널의 값을 가지고 오고싶을 때 사용한다.
  • 옵셔널 바인딩은 옵셔널의 값이 존재하는지 검사를 하고 존재한다면 그 값을 다른 변수에 대입시켜준다.
  • if let 또는 if var을 사용 한다.
  • 옵셔널의 값을 벗겨서 값이 있다면 if문 안으로 들어가고 값이 nil이라면 그냥 통과한다.
Ex)
if let opt = optBinding {
  print(opt) // optBinding의 값이 존재한다면 해당 값이 출력됩니다.
}
// optBinding의 값이 존재하지 않는다면 if문을 그냥 지나칩니다.

또한 if 문에서 , 로 구분하여 여러 옵셔널을 바인딩 할 수 있다.
이 곳에서 사용된 모든 옵셔널의 값이 존재해야 if문 안으로 진입한다.

var optBinding: String? = ""
var optName: String? = "유재우"
if let opt = optBinding, name = optName {
  // opt와 name의 값이 존재
}

Tip: 코드가 너무 길 경우에는, 여러 줄에 걸쳐서 사용하는 것이 바람직하다.

var optBinding: String? = ""
var optName: String? = "유재우"
if let name = optName,
  let opt = optBinding {
  // name과 opt 값이 존재
}
참고로, 두 번째 let 부터는 생략이 가능하다.
  • 옵셔널을 바인딩할 때 콤마(,)를 사용해서 조건도 함께 지정할 수 있다.
  • 콤마(,) 이후의 조건절은 옵셔널 바인딩이 일어난 후에 실행된다. 즉, 옵셔널이 벗겨진 값을 가지고 조건을 검사하게 된다.
var optAge: Int? = 25
if let age = optAge, age >= 20 {
  // age의 값이 존재하고, 20 이상이다.
}

Optional Chaining(옵셔널 체이닝)이란?

  • 옵셔널 체이닝은 옵셔널의 속성에 접근할 때, 옵셔널 바인딩 과정을 ? 키워드로 줄여주는 역할을 한다.

이런식으로 글로만 보면 이해가 잘 되지않아 예제를 보면서 이해하자.

  • 상황 설명
    옵셔널로 선언된 어떠한 배열 baeyul이 있다.
    이 배열이 비어있는지를 검사를 해야한다.
    그러려면 우선 배열이 nil이 아닌지를 확인하고 비어있는지 확인을 해야한다.
Ex) 
let baeyul: [String]? = [] // 옵셔널로 선언된 배열 생성
var binBaeyul = false 
if let baeyul = baeyul, baeyul.isEmpty { // 배열에 값이 있는지 확인 후에 baeyul이 비어있는지 확인한다.
  binBaeyul = true 
  print(binBaeyul) // 비어있을 때 참으로 값을 출력
} else {
  binBaeyul = false
  print(binBaeyul) //비어있지않을 때 거짓으로 값을 출력
}

이렇게 길고 복잡한 코드를 옵셔널 체이닝을 사용한다면?

let binBaeyul = baeyul?.isEmpty == true

앞서 말했듯이 옵셔널 체이닝은 옵셔널의 속성에 접근할 때, 옵셔널 바인딩 과정을 ? 키워드로 줄여주는 역할을 한다.

baeyul의 배열이 비어있거나 nil이거나 요소가 있을 경우 3가지 경우를 살펴보자.

  1. baeyul이 nil인 경우
baeyul?.isEmpty
-----/
baeyul? 까지 실행되고 'nil'을 반환
  1. baeyul이 빈 배열인 경우
baeyul?.isEmpty
---------------/
끝까지 실행되고 'true'를 반환
  1. baeyul에 요소가 있는 경우
baeyul?.isEmpty
---------------/
끝까지 실행되고 'false'를 반환

baeyul?.isEmpty의 결과로 나올 수 있는 값은 nil, true, false가 된다.
isEmpty의 반환값은 Bool인데, 옵셔널 체이닝으로 인해 Bool?을 반환하도록 바뀐 것이다.
따라서 값이 실제로 true인지를 확인하려면, == true를 해주어야 합니다.


강제 언래핑

  • 옵셔널 타입으로 감싸져 있는 값을 "?", "!"를 사용하여 강제로 풀어주는 작업을 뜻한다.
Ex) 
var option: int?
option = 25
print(option)     ->  Optional(25)
print(option!)    ->  25

? -> 자료형 뒤에

! -> 변수명 뒤에

  • 강제 언래핑을 사용하려는 값이 nil값이 아니라는 전제에 사용해야 한다.
var option: int?
option = 25
if option != nil { // 이런식으로 !를 사용할 때에 보험?을 들어야 한다.
   print(option!)
   }
else {
   print("nil")
   }
  • 가장 좋은 언래핑 방법은 옵셔널 바인딩이다.

Implicitly Unwrapped Optional(암묵적으로 벗겨진 옵셔널)

  • 옵셔널을 정의할 때 ? 대신 !를 붙이면 ImplicitlyUnwrappedOptional이라는 옵셔널로 정의된다.
  1. 값이 있을 때
var name: String! = "유재우"
print(name) // 유재우
  1. 값이 없을 때
var name: String!
print(name) // 오류
  1. 잘못된 타입일 때
var age: Int! = "25"
print(age) // 오류
  • 암묵적으로 벗겨진 옵셔널(!)을 사용할 때에는 변수 혹은 상수의 값이 nil이 아닐 거라는 확신을 가졌을 때 사용하는 것이 좋다.
  • 그래도 언래핑하려면 옵셔널 바인딩이나 옵셔널 체이닝 방법을 사용하는것이 가장 안전하고 좋은 방법이다.

공부한 블로그

profile
끝없이 탐구하는 iOS 개발자 유재우입니다!

0개의 댓글