2023년 1월 1일
08:00 AM
Buffering ...

최근 글 👑

[Swift-TIL] 옵셔널 바인딩, 체이닝 - 옵셔널 값을 안전하게 사용해 보기 (이론편)

2024. 10. 22. 22:00ㆍIOS/Swift-TIL
SMALL

옵셔널 바인딩과 체이닝에 대해 배운걸 끄적여 보겠다.

그전에 옵셔널을 이해하지 않았다면

옵셔널 이론편과 실습편을 충분히 이해를 하고 오길 권장한다.

옵셔널을 이해하지 않고 진행하면

바인딩, 체이닝 당연히 이해하기 어렵다.

 

이번 이론편은 조금 길어질 수 있으니 참고바란다.

나도 작성하면서 이렇게 길어질 줄 몰랐다...

 

옵셔널은 안전함을 추구하기 때문에 만들어졌다.

없음을 표현하고자 하고자 하는게 목표가 아니라는 거다.

옵셔널 자체는 안점함을 추구하기에 만들어졌음을 먼저 이해하자.

 

어떠한 값에 접근을 했을 때 없다면?

crash(크래시) 즉, 앱이 죽어버린다.

예를 들어보겠다.

let ABC = ["A", "B"]

let myAbc = ABC[3]

이렇게 예를 들었을 때

let ABC에 2도 없는 상태에서

3에 접근을 하려한다면,

펑.. 터진다.

당연히 지금은

0과 1밖에 없는 상태다.

 

그러면 어떻게 사용해야 안전한 걸까?

그때 필요한게 옵셔널이다.

그리고 그 옵셔널에서 옵셔널 바인딩,

옵셔널 체이닝 이러한 것들이 옵셔널 값을

안전하게 사용할 수 있도록 도와준다.

 

옵셔널 바인딩부터 알아보겠다.

바인딩은 묶는 것을 말한다.

어떠한 것을 잘 묶어 놓은 걸 바인딩이라고 한다.

 

옵셔널 바인딩은

옵셔널 안의 값을 꺼내는 작업을 말한다.

즉, 옵셔널에 있는 것을 잘 꺼내와서

묶어놓는것이다.

그래서

옵셔널 안에 값이 있는지 없는지를 확인한다고한다.

 

필자는 이렇게 들었을 때는 감이 잘 오질 않았다.

그래서 그림을 보고 이해를 했다.

이렇게 옵셔널 int가 있다고 했을 때

얘가 안에 있는지 없는지 모른다.

 

그렇다면, 만약에

이렇게 3이 들어 있다고 한다면,

옵셔널 3

이렇게 들어 있게 되는거다.

그리고, 만약에 없다면

이렇게 옵셔널 nil 이라고 들어있는 상태가 된다.

nil이 들어 있는거다.

 

"만약 옵셔널 안에 값이 있다면 사용할게"

이게 옵셔널 바인딩의 어떠한 기조이다.

 

그래서

 

" let petName: String? = "Pizza" "

 

let petName과 String Pizza 이러면

이제 petName은 String 문자열이고

얘가 만약에 이 안에 값이 있다면 쓰겠다.

없다면 안쓸래 라고 표현한다.

이를 살펴보면, 먼저

if let은 옵셔널 바인딩을 위한 키워드이다.

사실.. if 그리고 let은 따로따로 봐도 된다.

if 만약에 let Name은 petName 즉,

petName 이라는 값을 let Name에

할당할 수 있다면, nil이면 할당이 안되고,

값이 있다면 할당이 된다.

그래서

if문을 보고 변수가 할당이 된다, 안된다

참/거짓 이렇게 보기보다

그냥 if let을 하나의 키워드로 보는게 맞다.

옵셔널 바인딩을 위한 키워드

그렇기 때문에 변수 이름이 오고,

옵셔널 값이 들어가 있는

변수명이 와야한다는 것이다.

 

petName은 옵셔널이고,

이렇게 if let 뒤에 오는 변수는

저런 물음표를 없애 준다.

 

그래서 만약에 값이 들어 있다면(참),

노란색 안에 코드를 실행하고

분홍색으로 표기된 곳 name의 name은

string 옵셔널 타입이 아니라

string타입이 된다.


정리해보겠다.

if let 옵셔널 바인딩

"if let"은 옵셔널 바인딩을 위한 구문이다.

이를 통해 옵셔널 변수에 값이 있는지 확인하고,

그 값이 있을 경우 새로운 상수나

변수에 바인딩(할당)할 수 있다.

 

예를 들어,

petName이 옵셔널 타입이고

let petName: String? = "Pizza"로 정의되었다면,

if let 구문을 사용해서 petName

값이 있는지 확인할 수 있다.

 

옵셔널 바인딩 과정

if let을 사용할 때, 옵셔널 값에 실제로 값이 있을 경우,

해당 값을 새로운 변수에 할당한다.

이 변수는 더 이상 옵셔널 타입이 아니고,

안전하게 값에 접근할 수 있다.

if let name = petName {
    print(name)  // petName에 값이 있으면 이 코드가 실행
}

 

이 코드는 petNamenil이 아닐 경우,

즉 값이 있을 경우에만 실행된다.

이 때 nameString?이 아니라

String 타입으로, 옵셔널이 제거된 상태로

값을 사용하게 된다.

 

if let을 하나의 키워드처럼 이해

Swift에서 옵셔널 바인딩을 통해

값을 확인하고 사용할 때 흔히 사용하는 방법이다.

 

if let 구문을 사용하면, 옵셔널을 안전하게 언래핑할 수 있고,

nil이 아닐 때만 내부 코드가 실행된다.

 

옵셔널 타입 제거

옵셔널 바인딩을 통해 새로운 변수에 옵셔널 값을 할당하고,

그 변수를 사용하면 더 이상 옵셔널 처리가 필요하지 않는다.

let petName: String? = "Pizza"

if let name = petName {
    // 여기서 name은 String 타입으로 안전하게 사용
    print("이름은 \(name)이다.")  
} else {
    print("이름이 없다.")
}

 if let은 옵셔널 값에 안전하게 접근하기 위한 방법이고,

값이 있을 때만 그 값을 새로운 변수에

할당하고 사용할 수 있게 해준다.

 

if let을 통해 옵셔널 값이 nil인지 여부를 확인하고,

nil이 아닐 때 안전하게 그 값을 사용할 수 있다.

 

이렇게 이론적으로 정리해보고

실습편에서 다뤄보자.


다음으로 옵셔널 체이닝에 대해

알아본 내용을 끄적여보겠다.

체인은 여러개가 엮여 있는 형태를 이야기한다.

흔히들 아는 자전거체인, 사슬 등등

이러한 체인은 왜 필요하고,

필요하게 된 계기가 있는가?

 

음... 이런게 있을 수 있겠다.

struct People {
  let hobby: Hobby?
}

struct Hobby {
  let level: Int?
}

 

struct 해두고 People

let hobby는 옵셔널

즉, 사람이 있는데 그사람의 hobby는

있을 수도 있고, 없을 수도 있구나 라고 이해가 된다.

좋다, 그런데 이는 구조체이다.

그 안에 레벨이 존재하는데,

취미에 레벨이 있을수도 있고

없을 수도 있다.

 

바인딩을 여러번 해야한다

만약에 저런 레벨의 값을 꺼내려면 일단

People의 Hobby 값이 있는지 없는지

걸사를 해야하고,

Hobby 값이 있을 때

그 안에 있는 레벨이 있는지 없는지

검사를 해야한다.

 

즉, 옵셔널 바인딩을

여러번 중첩으로 해야한다는 것이다.

 

if let 안에 if let...

위 코드에서는 옵션이 2개라서

두번이지만, 굉장히 복잡한 형태라면,

옵셔널이 2개 3개 4개면

굉장히 피곤해진다.

 

그렇기 때문에

이러한 것들을 체인으로 엮어서

하나라도 nil이라면 nil 처리를 해주고

다 존재 한다면 한 번에 옵셔널 바인딩을

다 해서 그 값을 꺼내준다.

 

stayjun.hobby?.level

이렇게 점(.)으로 하면서

사이사이 물음표를 박아 두면

이게 옵셔널 체이닝이 된다.


간단하게 정리해보겠다.

 

옵셔널 체이닝의 기본 개념

옵셔널 체이닝은 옵셔널 값이 nil이 아닐 때만

당 속성이나 메서드에 접근할 수 있도록 하는 방법이다.

즉, 옵셔널 타입의 값에 여러 단계로 접근할 때,

중간에 어느 하나라도 nil이 있으면 바로 nil을 반환하고,

그렇지 않으면 그 값을 가져올 수 있다.

 

옵셔널 체이닝의 필요성

옵셔널 값이 중첩되어 있는 상황에서

하나씩 일일이 바인딩을 해야 한다면 매우 복잡해진다.

이 문제를 해결하기 위해 옵셔널 체이닝이 등장했다.

 

예를 들어, 다음과 같이 People 구조체가 있다고 가정해보겠다.

struct People {
  let hobby: Hobby?
}

struct Hobby {
  let level: Int?
}

let stayjun = People(hobby: Hobby(level: 5))

 

옵셔널 바인딩 없이 값을 접근하기

만약 stayjun.hobby?.level처럼

옵셔널 체이닝을 사용하면,

stayjunhobbynil이 아닐 경우에만

level에 접근할 수 있다.

이 과정에서 하나라도 nil이 있으면

자동으로 nil을 반환한다.

let level = stayjun.hobby?.level
print(level)  // Optional(5)

 

옵셔널 체이닝의 간결함

위 코드에서 hobbylevel

하나라도 nil이라면 전체가 nil이 된다.

하지만 이 과정에서 복잡한 바인딩을

여러 번 할 필요가 없다.

만약 옵셔널 체이닝 없이

이 과정을 처리하려면 이렇게 해야 했을 것이다.

if let hobby = stayjun.hobby {
    if let level = hobby.level {
        print(level)
    }
}

 

 

옵셔널 체이닝을 사용하면

한 줄로 간결하게 처리할 수 있다는 장점이 있다.

let level = stayjun.hobby?.level

 

이처럼 옵셔널 체이닝을 사용하면

중첩된 옵셔널에 접근할 때

매번 바인딩을 하지 않아도 되고,

하나라도 nil인 경우 자동으로 nil을 반환할 수 있어

코드를 간결하고 효율적으로 만들 수 있다.

 

이 또한 실습을 하며 더 깊이 알아가보고자 한다.

더보기
옵셔널 바인딩 정리

오른쪽 옵셔널 변수를 왼쪽에 바인딩하여

할당할 변수에 넣어주면,

name은 옵셔널이 아니게 되고,

옵셔널이 아닌 변수를 가지고

옵셔널 변수 안에 값이 들어있다면,

분홍색 영역은 실행한다.

 

옵셔널 체이닝 정리

앞 옵셔널 바인딩과 이어진다.

옵셔널 변수 자체가 복잡해져있는 형태

어떤것.어떤것.어떤것 이는

petName이 만약 옵셔널이라면의

뒤에 있는 녀석들은 옵셔널인 녀석들도 있을 것이고,

아닌 녀석들도 있을 텐데,

저 중에 옵셔널인 녀석들은 물음표 표시를 해서

이중에 하나라도 nil이 있다면,

이 바인딩은 이뤄지지 않는다,

만약 값이 다 들어 있다면,

한번에 바인딩을 중첩으로 하지 않고

한번에 name의 값을 바인딩 한다.

(실습에서는 Xcode가

옵셔널 체이닝을 알아서 붙여준다.)

 

 

728x90