大器晩成

옵셔널 체이닝 본문

iOS/Swift 문법

옵셔널 체이닝

zerobugpark 2024. 11. 12. 22:35

옵셔널 체이닝은 옵셔널 타입에 대해, 접근 연산자를 호출하는 방법입니다.

  • 옵셔널 체이닝의 결과는 항상 옵셔널입니다.
  • 옵셔널 체이닝에 값 중에서 하나라도, nil을 리턴한다면, 이어지는 표현식은 평가하지 않고 nil을 리턴합니다.
  • 옵셔널 타입으로 선언된 값에 접근해서, 속성, 메서드를 사용할 때 접근연산자(.) 앞에?(물음표) 붙여야 함

 

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}
let john = Person()

let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error

if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).")
} else {
    print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."
  • 강제 언래핑을 하기 위해 residence를 뒤에! 를 사용하면, residence는 값이 없기 때문에 오류가 발생합니다.
  • 스위프에서 residence의 프로퍼티를 체인하고  residence가 존재하면 numberOfRooms을 조회할 수 있도록 할 수 있습니다.

[Unwrapping]

// 1. 앞에 옵셔널타입에 값이 있다는 것이 확인한 경우
let roomCount = john.residence!.numberOfRooms

// 2. if let 바인딩
if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).")
} 

// 3. Nil-Coalescing 연산자
let defualtRooms = john.residence?.numberOfRooms ?? 10

 

 

함수 관련 표기법

class Cat {
    var name: String?
    
    var myMaster: (() -> Person?)?
    
    init(aFunction: @escaping () -> Person?) {
        self.myMaster = aFunction
    }
}


class Person {
    var name: String?
}


// 함수를 정의
func meowmeow() -> Person? {
    let person = Person()
    person.name = "Tim"
    return person
}


// 단순 예제
                           // 정의한 함수를 할당
var cat: Cat? = Cat(aFunction: meowmeow)

// myMaster? 함수에 대한 옵셔널
// mayMaster?()? 함수의 결과에 대한 옵셔널
var name = cat?.myMaster?()?.name               // Optional("Tim")
print(name)

 

딕셔너리 관련 표기법

class Person {
    var name: String?
}


class Stock {
    var stocks: [String: Person]?
}


var person1 = Person()
person1.name = "Jobs"
print(person1.name)


var person2 = Person()
person2.name = "Musk"
print(person2.name)



var stock = Stock()
stock.stocks = ["Apple": person1, "Tesla": person2]



stock.stocks?["Apple"]?.name
stock.stocks?["Tesla"]?.name

// 1. stocks?  ====> 딕셔너리 자체가 없을 수 있음을 의미
// 2. stocks?["Apple"]?  ====> 딕셔너리의 결과값이 없을 수 있음을 의미

 

 

옵셔널 체이닝에서 함수의 실행

class Bird {
    var name: String?
    var species: String
    
    init(name: String, species: String) {
        self.name = name
        self.species = species
    }
    
    func fly() {
        print("\(self.name)가 날고 있습니다.")
    }
    
    func eat() {
        print("음식을 먹고 있습니다.")
    }
}


var sparrow: Bird? = Bird(name: "참참이",species: "참새")

sparrow?.eat()          // 앞의 타입이 옵셔널이라고 해서 메서드가 실행이 안되는 것은 아님
sparrow?.fly()          // Optional("참참이")가 날고 있습니다.


sparrow = nil           // 타입에 값이 없음
sparrow?.eat()          // 타입의 값이 nil이면, 함수가 실행이 되지 않고 nil을 반환

[함수에 리턴형이 없는 경우]

  • 옵셔널 타입에 접근해서 사용하는 함수는 타입에 값이 있으면 함수를 실행합니다. (nil이 아니면 함수 실행)
  • 타입에 값이 없으면 nil이 출력됩니다.

[함수에 리턴형이 있는 경우]

  • 원래 리턴형이 옵셔널이 아니더라도, 타입에 값이 있으면 옵셔널 리턴 타입으로 반환
    타입에 값이 없으면 nil로 반환
728x90

'iOS > Swift 문법' 카테고리의 다른 글

클래스와 구조체의 차이  (0) 2024.11.21
구조체(Struct)와 클래스(Class)  (1) 2024.11.21
inout 파라미터  (0) 2024.11.08
Swift 제어전송문  (0) 2024.11.08
함수의 오버로딩  (1) 2024.11.08