1,swift为什么有可选类型值?
如果一个常量,或变量,它的值可能存在,也可能不存在,那么可以定义这个值为可选类型值。这样做的好处就是,它不存在的时候,自动为nil(swift里面nil跟OC中不一样,swift的nil指可选类型值不存在,OC中的nil指对象为空)
我的理解是,可选类型值,是普通的常量或变量做了封装,加了个壳,如果要用这个值,就需要解包。
解包有两种方式,(1)隐式解包 (2)显式解包
(1)隐式解包,就是在定义可选类型值的时候,加上“!”进行强制解包
如,@IBOutlet var dotImageView: UIImageView!
这样用的时候,就不用再解包,可以直接使用,如
dotImageView.transform = CGAffineTransformMakeTranslation(-view.frame.width, 0)
(2)显示解包,即在用的时候,加!
如 @IBOutlet var dotImageView: UIImageView?
dotImageView!.transform = CGAffineTransformMakeTranslation(-view.frame.width, 0)
(3)用的时候,也可以加?去解包
意思是解包获得的值可能是nil
2,解包用的时候,分常见二种情况
(1)接着调用解包后的对象的属性,方法,子脚步等
(2)需要用到解包后的值
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
john.residence = Residence()
//用到解包后的属性 可? 可!(!解包在运行时候,可能导致崩溃)
john.residence?.numberOfRooms = 1
let roomCount = john.residence?.numberOfRooms
if roomCount != nil {
//已经确定不为空,就可强制解包!,不能用?
var count = 1 + roomCount!
print("count=\(roomCount)")
print("count=\(count)")
}else {
print("nil")
}
(3)多层解包情况
class Person {
var residence: Residence?
}
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 != nil {
return buildingName
} else if buildingNumber != nil {
return buildingNumber
} else {
return nil
} }
}
class Residence {
var rooms: Array= []
var numberOfRooms: Int {
return rooms.count
}
subscript(i: Int) -> Room {
return rooms[i]
}
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
var address: Address?
}
//通过可选链调用属性
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
print("count=\(roomCount)")
}else{
print("unable get roomCount")
}
//通过可选链调用方法
john.residence?.printNumberOfRooms()
//使用可选链调用子脚本
if let firstRoomName = john.residence?[0].name {
print("The first room name is \(firstRoomName).")
} else {
print("Unable to retrieve the first room name.")
}
let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name:"aa"))
john.residence = johnsHouse
if let firstRoomName = john.residence?[0].name {
print("The first room name is \(firstRoomName).")
} else {
print("Unable to retrieve the first room name.")
}
//连接多层链接
if let johnsStreet = john.residence?.address?.street {
print("John's street name is \(johnsStreet).")
} else {
print("Unable to retrieve the address.")
}
let john1 = Person()
let johnsAddress = Address()
johnsAddress.buildingName = "The Larches"
johnsAddress.street = "Laurel Street"
john1.residence?.address = johnsAddress
if let johnsStreet = john1.residence?.address?.street {
print("John's street name is \(johnsStreet).")
} else {
print("Unable to retrieve the address.")
}