swift 0x12
optional chaining
문현진(arnold@css99.co.kr)
오늘은 뭘 바를까? 이번 신상은 뭘까? 궁금한 언니들은 구글 플레이에
서 “마메스"를 검색하세요.
옵셔널 체인
옵셔널 값이 nil인가요?
forced unwrapping
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
let roomCount = john.residence.numberOfRooms
forced unwrapping
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
let roomCount = john.residence.numberOfRooms
Runtime Error
forced unwrapping
nil인지 물어본다. (john.residence == nil)
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has (roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."
forced unwrapping
nil인지 물어본다. (john.residence != nil)
john.residence = Residence()
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has (roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."
옵셔널 체인을 위한 모델 클래스 선언
class Person {
var residence: Residence?
}
class Residence {
var rooms = Room[]()
var numberOfRooms: Int {
return rooms.count
}
subscript(i: Int) -> Room {
return rooms[i]
}
func printNumberOfRooms() {
println("The number of rooms is
(numberOfRooms)")
}
var address: Address?
}
옵셔널 체인을 위한 모델 클래스 선언
class Room {
let name: String
init(name: String) { self.name = name
}
}
class Address {
var buildingName: String?
var buildingNumber: String?
var street: String?
func buildingIdentifier() -> String? {
if buildingName {
return buildingName
} else if buildingNumber {
return buildingNumber
} else {
return nil
}
}
}
옵셔널 체인을 통한 프로퍼티 호출
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has (roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."
옵셔널 체인을 통한 메소드 호출
func printNumberOfRooms() {
println("The number of rooms is (numberOfRooms)")
}
if john.residence?.printNumberOfRooms() {
println("It was possible to print the number of rooms.")
} else {
println("It was not possible to print the number of rooms.")
}
// prints "It was not possible to print the number of rooms."
옵셔널 체인을 통한 서브스크립트 호출
if let firstRoomName = john.residence?[0].name {
println("The first room name is (firstRoomName).")
} else {
println("Unable to retrieve the first room name.")
}
// prints "Unable to retrieve the first room name."
옵셔널 체인을 통한 서브스크립트 호출
let johnsHouse = Residence()
johnsHouse.rooms += Room(name: "Living Room")
johnsHouse.rooms += Room(name: "Kitchen")
john.residence = johnsHouse
if let firstRoomName = john.residence?[0].name {
println("The first room name is (firstRoomName).")
} else {
println("Unable to retrieve the first room name.")
}
// prints "The first room name is Living Room."
여러 단계의 체인 연결
if let johnsStreet = john.residence?.address?.street {
println("John's street name is (johnsStreet).")
} else {
println("Unable to retrieve the address.")
}
// prints "Unable to retrieve the address."
여러 단계의 체인 연결
let johnsAddress = Address()
johnsAddress.buildingName = "The Larches"
johnsAddress.street = "Laurel Street"
john.residence!.address = johnsAddress
if let johnsStreet = john.residence?.address?.street {
println("John's street name is (johnsStreet).")
} else {
println("Unable to retrieve the address.")
}
// prints "John's street name is Laurel Street."
옵셔널 반환값을 이용한 메소드 체인
if let buildingIdentifier = john.residence?.address?.buildingIdentifier() {
println("John's building identifier is (buildingIdentifier).")
}
// prints "John's building identifier is The Larches."
if let upper = john.residence?.address?.buildingIdentifier()?.uppercaseString {
println("John's uppercase building identifier is (upper).")
}
// prints "John's uppercase building identifier is THE LARCHES."

Swift 0x12 optional chaining

  • 1.
    swift 0x12 optional chaining 문현진(arnold@css99.co.kr) 오늘은뭘 바를까? 이번 신상은 뭘까? 궁금한 언니들은 구글 플레이에 서 “마메스"를 검색하세요.
  • 2.
  • 3.
    forced unwrapping class Person{ var residence: Residence? } class Residence { var numberOfRooms = 1 } let john = Person() let roomCount = john.residence.numberOfRooms
  • 4.
    forced unwrapping class Person{ var residence: Residence? } class Residence { var numberOfRooms = 1 } let john = Person() let roomCount = john.residence.numberOfRooms Runtime Error
  • 5.
    forced unwrapping nil인지 물어본다.(john.residence == nil) if let roomCount = john.residence?.numberOfRooms { println("John's residence has (roomCount) room(s).") } else { println("Unable to retrieve the number of rooms.") } // prints "Unable to retrieve the number of rooms."
  • 6.
    forced unwrapping nil인지 물어본다.(john.residence != nil) john.residence = Residence() if let roomCount = john.residence?.numberOfRooms { println("John's residence has (roomCount) room(s).") } else { println("Unable to retrieve the number of rooms.") } // prints "Unable to retrieve the number of rooms."
  • 7.
    옵셔널 체인을 위한모델 클래스 선언 class Person { var residence: Residence? } class Residence { var rooms = Room[]() var numberOfRooms: Int { return rooms.count } subscript(i: Int) -> Room { return rooms[i] } func printNumberOfRooms() { println("The number of rooms is (numberOfRooms)") } var address: Address? }
  • 8.
    옵셔널 체인을 위한모델 클래스 선언 class Room { let name: String init(name: String) { self.name = name } } class Address { var buildingName: String? var buildingNumber: String? var street: String? func buildingIdentifier() -> String? { if buildingName { return buildingName } else if buildingNumber { return buildingNumber } else { return nil } } }
  • 9.
    옵셔널 체인을 통한프로퍼티 호출 let john = Person() if let roomCount = john.residence?.numberOfRooms { println("John's residence has (roomCount) room(s).") } else { println("Unable to retrieve the number of rooms.") } // prints "Unable to retrieve the number of rooms."
  • 10.
    옵셔널 체인을 통한메소드 호출 func printNumberOfRooms() { println("The number of rooms is (numberOfRooms)") } if john.residence?.printNumberOfRooms() { println("It was possible to print the number of rooms.") } else { println("It was not possible to print the number of rooms.") } // prints "It was not possible to print the number of rooms."
  • 11.
    옵셔널 체인을 통한서브스크립트 호출 if let firstRoomName = john.residence?[0].name { println("The first room name is (firstRoomName).") } else { println("Unable to retrieve the first room name.") } // prints "Unable to retrieve the first room name."
  • 12.
    옵셔널 체인을 통한서브스크립트 호출 let johnsHouse = Residence() johnsHouse.rooms += Room(name: "Living Room") johnsHouse.rooms += Room(name: "Kitchen") john.residence = johnsHouse if let firstRoomName = john.residence?[0].name { println("The first room name is (firstRoomName).") } else { println("Unable to retrieve the first room name.") } // prints "The first room name is Living Room."
  • 13.
    여러 단계의 체인연결 if let johnsStreet = john.residence?.address?.street { println("John's street name is (johnsStreet).") } else { println("Unable to retrieve the address.") } // prints "Unable to retrieve the address."
  • 14.
    여러 단계의 체인연결 let johnsAddress = Address() johnsAddress.buildingName = "The Larches" johnsAddress.street = "Laurel Street" john.residence!.address = johnsAddress if let johnsStreet = john.residence?.address?.street { println("John's street name is (johnsStreet).") } else { println("Unable to retrieve the address.") } // prints "John's street name is Laurel Street."
  • 15.
    옵셔널 반환값을 이용한메소드 체인 if let buildingIdentifier = john.residence?.address?.buildingIdentifier() { println("John's building identifier is (buildingIdentifier).") } // prints "John's building identifier is The Larches." if let upper = john.residence?.address?.buildingIdentifier()?.uppercaseString { println("John's uppercase building identifier is (upper).") } // prints "John's uppercase building identifier is THE LARCHES."

Editor's Notes

  • #3 예를 들어서 옵셔널은 실제로 값이 있을 수도 있고, nil 일 수도 있다. nil인 경우에 강제로 접근하면 fatal error가 난다. 따라서 nil을 자연스럽게 처리 하기 위해서 옵셔널 체인이 있다.
  • #8 여기서는 person 의 residence 그리고 residence의 address가 모두 옵셔널이다.
  • #9 address에는 buildingIdentifier라는 String?을 반환하는 메소드가 있다. 이 메소드는 buildingName, buildingNumber 를 확인해서 nil 을 반환한다.
  • #10 이전 처럼 residence가 nil이기 때문에 에러없이 실패한다.
  • #11 여기서 printNumberOfRooms는 반환값이 없다. 반환값이 없으면 암시적으로 void를 반환한다. 그러나, 옵셔널변수를 사용하기 떄문에 void가 아니라 void?를 반환 할 것이다. 옵셔널 체인을 통해서 함수를 호출하면 항상 반환 값을 가지기 떄문이다. 그래서 아래 함수가 같이 사용해서 호출이 가능한지 확인 할 수 있다.
  • #12 여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
  • #13 여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
  • #14 여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
  • #15 여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
  • #16 buildingIdentifier()는 원래 String? 타입의 값을 반환한다. 이 이상의 옵셔널 체인을 반환하려면 괄호뒤에 옵셔널 체인 물음표를 쓴다. 왜냐하면 묶으려는 옵셔널 값이 buildingIndentifier가 아니라 buildingIndentifier메소드의 반환 값이기 때문이다.