애플 스위프트 언어 개발 가이드를 기반으로 초기화 관련된 내용을 정리했습니다. 초기화가 복잡합니다. 크게 복잡하지 않을 수도 있는 내용이지만 언어마다 조금씩 다른 부분을 잘 정리했습니다.
http://cafe.naver.com/architect1 에서 스터디 진행중입니다.
기본적인 뼈대는 http://swift.leantra.kr/ 를 기반으로 합니다.
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."
Notas del editor
예를 들어서 옵셔널은 실제로 값이 있을 수도 있고, nil 일 수도 있다. nil인 경우에 강제로 접근하면 fatal error가 난다. 따라서 nil을 자연스럽게 처리 하기 위해서 옵셔널 체인이 있다.
여기서는 person 의 residence 그리고 residence의 address가 모두 옵셔널이다.
address에는 buildingIdentifier라는 String?을 반환하는 메소드가 있다. 이 메소드는 buildingName, buildingNumber 를 확인해서 nil 을 반환한다.
이전 처럼 residence가 nil이기 때문에 에러없이 실패한다.
여기서 printNumberOfRooms는 반환값이 없다. 반환값이 없으면 암시적으로 void를 반환한다. 그러나, 옵셔널변수를 사용하기 떄문에 void가 아니라 void?를 반환 할 것이다. 옵셔널 체인을 통해서 함수를 호출하면 항상 반환 값을 가지기 떄문이다.
그래서 아래 함수가 같이 사용해서 호출이 가능한지 확인 할 수 있다.
여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
여기서 물음표는 john.residence바로 뒤에 있어야 한다. 왜냐하면 residence가 옵셔널 체인을 사용할 옵션 값이기 떄문이다.
buildingIdentifier()는 원래 String? 타입의 값을 반환한다.
이 이상의 옵셔널 체인을 반환하려면 괄호뒤에 옵셔널 체인 물음표를 쓴다. 왜냐하면 묶으려는 옵셔널 값이 buildingIndentifier가 아니라 buildingIndentifier메소드의 반환 값이기 때문이다.