iOS

웹개발자의 iOS 개발기(4) - 옵셔널, 옵셔널 바인딩, 체이닝

whh__ 2025. 1. 19. 20:39

옵셔널, 옵셔널 바인딩, 체이닝에 대하여 공부해 보았습니다.

06. 옵셔널- 있을 수 있는 것과 없는 것

옵셔널

  • 있을 수도 있고 없을 수도 있는 값
  • 타입 뒤에 ?를 붙여서 선언
    • let name: String? = “”
  • 있으면 값이 있고, 없으면 nil
  • 0은 0만큼 있는 것
  • 정말 없는 것을 nil
import SwiftUI

struct _6_Optional_nil_: View {
    
    var name: String = "조우현"
    var petName: String?
    var car: String? = "붕붕이"
    
    var body: some View {
        VStack {
            Text("이름은 \\(name) 입니다. 펫 이름은 \\(petName) 입니다. 차 이름은 \\(car) 입니다")
        }
        
        .onAppear() {
            print("이름은 \\(name) 입니다. 펫 이름은 \\(petName) 입니다. 차 이름은 \\(car) 입니다")
        }
    }
}

#Preview {
    _6_Optional_nil_()
}

07. 옵셔널 바인딩, 체이닝 - 옵셔널 값을 안전하게 사용하기

옵셔널은 안전함을 추구

  • 없음을 표현하고 싶은게 아니라 안전함을 위해서 만들어졌다.
  • 어떤 값에 접근하려 할 때 없다면 → 크래쉬
  • 옵셔널 바인딩, 옵셔널 체이닝

옵셔널 바인딩

  • 바인딩 → 묶는것
  • 옵셔널 안에 있는 값을 꺼내는 작업
  • 옵셔널 안에 값이 있는지 없는지 확인
  • 만약 옵셔널 안에 값이 있다면 사용
let petName: String? = "coco"

// "if" + "let" 각각의 키워드로 보는게 아닌, "if let" 이라는 하나의 키워드로 바라보자.
// petName의 값이 있다면 옵셔널이 아닌 데이터를 가지고 중괄호({}) 실행
if let name = petName {
	print(name) 
}

옵셔널 체이닝

  • 체인 - 여러개가 엮여있는 형태
  • 구조체의 구조체 형태를 가지고 있다고 가정
  • struct People { let hobby: Hobby? } struct Hobby { let level: Int? }
  • 이 구조라면 바인딩을 여러번 해야 함
    • if let 안에 if let 안에..
  • 체인으로 엮어서 하나라도 nil이면 nil
  • leeo.hobby?.level 하나로 해결
import SwiftUI

struct _7_Optional: View {
    
    var leeo: People?  = People(name: "Leeo",  mbti: MBTI(name: "ENFP"))
    var bami  = People(name: "bami",  petName: "coco")
    var berry = People(name: "berry", petName: "cookie")
    
    var body: some View {
        VStack {
            
//            if let petName = leeo.petName {
//                Text("이름은 \\(leeo.name) 애완동물 이름은 \\(petName)")
//            } else {
//                Text("이름은 \\(leeo.name) 애완동물 이름은 없어요")
//            }
//            
//            if let petName = bami.petName {
//                Text("이름은 \\(bami.name) 애완동물 이름은 \\(petName)")
//            } else {
//                Text("이름은 \\(bami.name) 애완동물 이름은 없어요")
//            }
//            
//            if let petName = berry.petName {
//                Text("이름은 \\(berry.name) 애완동물 이름은 \\(petName)")
//            } else {
//                Text("이름은 \\(berry.name) 애완동물 이름은 없어요")
//            }
            
            
            // 너무 힘든 옵셔널 바인딩
            if let leeo = leeo {
                if let mbti = leeo.mbti {
                    if let name = mbti.name {
                        
                    }
                }
            }
            
            // 옵셔널 체이닝을 사용하자
            if let leeoMbtiName = leeo?.mbti?.name {
                Text(leeoMbtiName)
            } else {
                Text("No MBTI name")
            }
            
        }
    }
}

struct People {
    let name: String
    var petName: String?
    var mbti: MBTI?
}

struct MBTI {
    let name: String?
}

#Preview {
    _7_Optional()
}