用“可选链”而不用“强制解包”
class Person{
var residence: Residence?//residence是住所的意思
}
class Residence{
var numberOfRoomes = 1
}
两个类“Person”和“Residence“,现在假如我创建了一个新的Person实例,他的residence属性因为是可选值,所以被初始化为nil,如下
let john = Person()//此时john的residence属性为nil
如果这时使用感叹号( ! )强制解包numberOfRoomes会因为residence的值为nil而崩溃。
let aErrorExample = john.residence!.numberOfRooms//运行时会报错
为此,可选链式调用提供了另一种访问numberOfRooms的方式,使用( ? )来代替原来的感叹号( ! )
if let roomCount = john.residence?.numberOfRooms{
print("john's residence has \(roomCount) rooms.")
}else{
print("Unable to retrieve the number of rooms.")
}
后缀问号( ? )的作用是在该值不为nil 的情况下访问,记住上面这种写法,你可能会经常遇到if let xxx = xxx这种形式
访问失败(值为nil)时则返回
- 看到这里,你已经完成了对基础链式调用理论的学习,不妨看看开发中可能碰到的例子?
class Person {
var residence: Residence?
}
class Residence {
var rooms = [Room]()
var numberOfRooms: Int {
return rooms.count
}
class Room {
let name: String
init(name: String) {self.name = name}
}
//subscript是下标的意思:传入一个下标数字,返回需要的那个房间
subscript(i: Int) -> Room {
get{
return rooms[i]
}
set{
rooms[i] = newValue
}
}
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
var address: Address?
}
仔细看下代码!其中Address类会在下方给出,其他应该都能看懂
class Address {
var buildingName: String?
var buildNumber: String?
var street: String?
func buildingID() -> String? {
if bildingName != nil {
return buildingName
}else if let buildingNumber = buildingNumber, let street = street{
return "\(buildingNumber \(street))"
}else{
return nil
}
}
}
可以看出Address类中含有大量的可选值,buildingID提供了一个用来表示某个建筑方法:如果它有名字那直接返回名字,如果它没名字,那就看看它是否同时拥有buildNumber和street,有则返回一个拼接的字符串没有则返回nil
仔细看看黄字是怎么实现的 ! ! !
- 好了看完了例子,我想你应该知道该怎么访问一个可选值了
let john = Person()
if let roomCount = john.residence?.numberOfRooms{
print("john has \(roomCount)'s rooms")
}else{
return nil
}
我们对john已经进行了初始化所以residence存在了就可以访问的到