swift中可選值?和!使用的方法示例
Optional 可選值
Optional是 Swift 的一大特色,也是 Swift 初學(xué)者最容易困惑的問題。
定義變量時(shí),如果指定該變量是可選的,表示該變量可以有一個指定類型的值,也可以是 nil。
此外,Swift的nil也和Objective-C有些不一樣,在Objective-C中,只有對象才能為nil,而在Swift里,當(dāng)基礎(chǔ)類型(整形、浮點(diǎn)、布爾等)沒有值時(shí),也是nil,而不是一個初始值,沒有初始值的值,是不能使用的,這就產(chǎn)生了Optional類型。定義一個Optional的值很容易,只需要在類型后面加上問號(?)就行了,如:
var str: String?
一個Optional值和非Optional值的區(qū)別就在于:Optional值未經(jīng)初始化雖然為nil,但普通變量連nil都沒有:
//未被初始化,但是是一個Optional類型,為nil var str: String? str //輸出nil //未被初始化,也不是Optional類型 var str2: String str2 //使用時(shí)出錯
關(guān)于可選值 !和 ? 使用
先來看一個栗子
class House {
//房子有幾個房間
var numRooms:Int = 5
}
class Person {
//一個人可能有房子也可能沒有房子,所以將房子的屬性設(shè)為可選
var house: House?
}
let xiaowang = Person()
//此時(shí)xiaowang沒有房子
//如果試圖調(diào)用xiaowang的house屬性,訪問house的numRooms屬性。過程如下:
//1. 第一種方式: 將house強(qiáng)行解包,用 !。但此時(shí) house 沒有值,所以結(jié)果是直接崩潰的。
let numroom = xiaowang.house!.numRooms
//2. 用 if let
if let house = xiaowang.house {
let roomCount = house.numRooms
}
//3. 用 ?
if let numRooms = xiaowang.house?.numRooms {
let numroom = numRooms
}
現(xiàn)在問題來了
- house后面怎么可以直接接問號呢?不是接了問號編譯器就知道它是否有值會報(bào)錯嗎?
- house的numRooms屬性不是必選屬性嗎? 為什么用if let來做可選綁定了呢?
這個涉及到一個新的知識,叫可空鏈?zhǔn)秸{(diào)用。
可空鏈?zhǔn)秸{(diào)用。是指當(dāng)調(diào)用可選一個對象的屬性或方法時(shí),可以直接使用問號,此時(shí),不管它的屬性是否可選。最終都返回一個該可選值。
可空鏈?zhǔn)秸{(diào)用
可空鏈?zhǔn)秸{(diào)用。是指當(dāng)調(diào)用一個 可選對象 的屬性和方法時(shí)??梢韵炔粚υ摽蛇x對象強(qiáng)行解包。直接使用?此時(shí) 可選 這個特征,一直往后傳遞到 最后要調(diào)用的屬性和方法,最后返回一個可選的值的過程。
還舉上面的例子。
if let numRooms = xiaowang.house?.numRooms {
let numroom = numRooms
}
此時(shí)調(diào)用的是可選對象 house 的 numRooms屬性。滿足條件:
- house是可選對象
- 調(diào)用可選對象 house 的屬性 numRooms
- 此時(shí)不用給可選對象 house 強(qiáng)行解包
- 可選這個特征,傳遞給了 numRooms
- 所以,返回一個numRooms 的可選值。
再舉個栗子
class Room {
//房間有四個窗子
var numWindows:Int = 4
}
class House {
//房子有幾個房間
var room: Room?
}
class Person {
//一個人可能有房子也可能沒有房子,所以將房子的屬性設(shè)為可選
var house: House?
}
let windows = Person().house?.room?.numWindows
if let w = windows {
//windows是可選值
}
- 訪問了一個 可選對象 house的屬性Room
- 那么 house 不用強(qiáng)行解包,不用管Room之前是否可選,此時(shí)可選的特征傳給了Room,那么Room也變成了可選。
- 再訪問可選對象 Room 的 numWindows屬性,此時(shí)可選特征傳遞給 numWindows。
- 返回一個可選的 numWindows. 此時(shí) windows 是可選的。
再說說調(diào)用可選對象的方法
調(diào)方法的原理是一樣的。
先說方法。在swift中任何方法都有返回值。沒有返回值,只是說它返回了Void。Void也是一個返回值。
如果調(diào)用可選對象的某個方法。則可選對象的 可選特征 會自動傳遞給該方法的返回值。
舉個栗子:
class Room {
//房間有四個窗子
var numWindows:Int = 4
func closeWindow() {
print("關(guān)窗")
}
}
class House {
//房子有幾個房間
var room: Room?
func closeDoor() {
print("關(guān)門")
}
}
class Person {
//一個人可能有房子也可能沒有房子,所以將房子的屬性設(shè)為可選
var house: House?
}
let person = Person()
//下面這一句,house 的可選特征,傳給了 closeDoor() 的返回值 Void, 所以實(shí)際上返回的是一個 可選的Void類型
person.house?.closeDoor()
//所以,判斷方法是否存在,可以判斷是否為 nil
if person.house?.closeDoor() != nil {
//closeDoor關(guān)門的方法調(diào)用成功了
}
if person.house?.room?.closeWindow() != nil {
//closeWindow 關(guān)窗的方法調(diào)用成功了
}
如果你不關(guān)心是否調(diào)用成功,則判斷是否為nil那一步不是必須的
最后做個總結(jié)
- 訪問可選對象的屬性或方法時(shí),可以用 ? 號
- 訪問可選對象的屬性時(shí),從 ?后面都變可選了,返回的一定是一個可選值。
- 訪問可選對象的方法時(shí)。判斷是否為 nil 來確認(rèn)方法是否并調(diào)用成功。
來看項(xiàng)目當(dāng)中的栗子
//先看調(diào)用屬性
class PersonCell: UITableViewCell {
var person: Person? {
didSet {
//此兩處,person是可選的。訪問person的屬性用?,返回的是一個可選的 name
textLabel?.text = person?.name
detailTextLabel?.text = person?.phone
}
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .Subtitle, reuseIdentifier: reuseIdentifier)
accessoryType = .DisclosureIndicator
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//再看調(diào)方法
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let detailVC = DetailViewController()
detailVC.person = persons[indexPath.row]
detailVC.finishedCallBack = {
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Top)
}
//此處, navigationController是一個可選屬性,則 pushViewController 方法返回一個可選的Void。navigationController?.pushViewController(detailVC, animated: true)
}
//要想判斷 pushViewController 是否成功,可以做下面的活
if navigationController?.pushViewController(detailVC, animated: true) != nil {
//推成功了
}
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
SwiftUI 登錄界面布局實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了SwiftUI 登錄界面布局實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動態(tài)倒計(jì)時(shí)功能
這篇文章主要介紹了Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動態(tài)倒計(jì)時(shí)功能的相關(guān)資料,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
在Swift中使用Cocoa的現(xiàn)有設(shè)計(jì)模式介紹
這篇文章主要介紹了在Swift中使用Cocoa的現(xiàn)有設(shè)計(jì)模式介紹,Cocoa是蘋果公司為Mac OS X所創(chuàng)建的原生面向?qū)ο蟮腁PI,是Mac OS X上五大API之一,需要的朋友可以參考下2014-07-07
Swift仿選擇電影票的效果并實(shí)現(xiàn)無限/自動輪播的方法
這篇文章主要給大家介紹了關(guān)于Swift仿選擇電影票的效果并實(shí)現(xiàn)無限/自動輪播的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08

