Swift - Optional chaining ( iOS )

김제형·2024년 11월 18일

이 글은 주인장이 언제 봐도 또 iOS, Swift 쪽으로 관심이 생기기 시작한 사람이 봤을때 이해를 도와주는 글이다.

피드백은 언제나 환영이야~!

Optional chaining

  • 옵셔널 체이닝 - ?. 을 붙여 값이 존재할 떄만 결과값을 출력하는 코드

optional chaining 은 옵셔널 변수로 선언된 변수(상수)를 강제 언래핑( ! )을 하지 않고 값을 도출해내는 방법중에 하나 이다.

옵셔널 체이닝이 강제 언래핑, 옵셔널 바인딩과 다른점

optional binding ( if~let , guard~let ) 과 강제 언래핑 ( ! )은 실행 후 값이 옵셔널 값이 아닌 일반 값으로 나온다

if let String, guard let String, String! => String반환

하지만 옵셔널 체이닝은 ?.을 걸어 값을 출력하게 되면 다른 대처방법과 다르게 옵셔널 값을 나온다는 점이다.

var name : String?
Class?.name => optional String 반환

옵셔널 체이닝과 바인딩의 분리 이유

  • 먼저 두개의 분리 이유는 의도와 사용방식의 차이가 있기 때문이다.

옵셔널 체이닝

옵셔널 체이닝은 여러 단계의 프로퍼티를 한줄로 안전하게 접근이 가능하다 하지만 옵셔널 값으로 반환을 하기 때문에 추가처리가 필요할 수도 있다

옵셔널 바인딩

옵셔널 바인딩은 옵셔널 값 자체를 일반형으로 바꾸는 것이 목적이다.

결과

  1. 체이닝은 값이 없어도 진행 -> 결과를 옵셔널로 유지
  2. 바인딩은 값이 있는 경우는 언래핑해서 사용하고 값이 존재하지 않으면 다른 로직처리

예제

class Number{
	var num : int
    var avg : avg?
}

Int? vs Avg? 의 차이

하지만 num은 Int로 선언되었고 avg는 Avg? 로 선언 되었다.
왜 같은 자료형을 선언하는데 num과 avg는 자료형이 다를까?

  • 이는 따른 대답은 사용하는 용도가 다르다는 것이다.
var num : Int?
var car : Car?
  • 위 예제는 모두 옵셔널 체이닝이 가능하다 하지만 위에서 말했드시 사용하는 용도가 다르다.

Int? 와 Avg? 는 모두 옵셔널형으로 선언되었지만 Int는 데이터 타입( Int )으로 단순한 데이터 타입만 다루고

Avg? 는 같은 옵셔널 형이지만 인스턴스와 그 속성들에 접근할 때 사용한다는 점이 다르다.

var name: String? = "Alice"
var car: Car? = Car(model: "Tesla", owner: nil)

// 1. String? 접근
if let nameLength = name?.count { 
// name이 nil이 아니면 count를 계산
    print("이름의 길이는 \(nameLength)자입니다.")
} else {
    print("이름이 없습니다.")
}

// 2. Car? 접근
if let carModel = car?.model {
// car와 model이 nil이 아니면 model 값 출력
    print("차 모델은 \(carModel)입니다.")
} else {
    print("차가 없습니다.")
}
//chat gpt 예제 생성

옵셔널 바인딩과 체이닝의 결합사용

if let carModel = car?.model {
// car와 model이 nil이 아니면 model 값 출력
    print("차 모델은 \(carModel)입니다.")
}else {
    print("차가 없습니다.")
}

위 코드에선 옵셔널 바인딩( if let ~ )과 옵셔널 체이닝( car?.model ) 을 결합한 방식이다.

이렇게 하게 되면 옵셔널로 선언된 car 속성에 옵셔널로 선언된 car의 속성인 model을 안전하게 접근할 수 있다.

설명
1. if let(옵셔널바인딩)으로 carModel 을 옵셔널로 부터 자유롭게 해준다
2. 옵셔널로 선언된 model을 사용하기 위해 옵셔널체이닝을 걸어줘 값의 존재 여부를 판단한다.
3. 옵셔널 model에 대한 값이 존재하게 된다면 옵셔널바인딩을 한 car 클래스 model에 값을 대입하게 된다.
4. 결과적으로 안정적으로 model의 값을 도출해 낼 수 있다.

  • model에 값이 nil로 할당되어 있다면 else문을 출력하게 된다.

옵셔널 바인딩의 guard let 문 활용

if let과 guard let 문은 활용도가 비슷하다고 판단하므로 이 단락을 만든다.

func carCheck(){
    guard let carModel = car?.model else{
        print("차가 없습니다.")
     return
    } 
    print("차 모델은 \(carModel)입니다.")
}

carCheck()

guard let문은 함수나 메서드 내에서 자주 사용하므로 함수 안에 넣어 값이 nil 이면 "차가 없습니다." 가 출력되게 되고,
nil이 아닌 값이 할당되어 있으면 "차 모델은 (carModel)입니다."이 출력되게 된다.

profile
개발자 지망생

0개의 댓글