Swift是強(qiáng)類型語言睁搭,但也允許開發(fā)者通過is、as笼平?和as园骆!這三種操作來對(duì)類型進(jìn)行判斷和強(qiáng)制轉(zhuǎn)換。其中is用作類型判斷寓调,而as锌唾?和as!則分別是類型轉(zhuǎn)換的可選形式和強(qiáng)制形式夺英。在這里強(qiáng)調(diào)一下晌涕,swift中比較常用的向下轉(zhuǎn)換(downcast)是沒有as操作符的。
is操作符
is操作用來判斷某一個(gè)對(duì)象是否是某一個(gè)特定的類痛悯,它會(huì)返回一個(gè)bool類型的值余黎。is操作的邏輯很簡單,某一個(gè)類的對(duì)象肯定是自己這個(gè)類载萌,也一定是自己的超類惧财,但超類的對(duì)象不是子類。如果兩個(gè)類沒有繼承關(guān)系扭仁,那is操作一定返回false.
as垮衷!操作符
as!操作符是類型轉(zhuǎn)換的強(qiáng)制格式乖坠,優(yōu)點(diǎn)在于代碼簡單搀突,如果可以轉(zhuǎn)換,則會(huì)返回轉(zhuǎn)換了格式的對(duì)象熊泵,如果無法轉(zhuǎn)換就會(huì)拋出運(yùn)行時(shí)錯(cuò)誤仰迁。因此除非百分之百確定可以轉(zhuǎn)換,否則不應(yīng)該使用as顽分!來進(jìn)行強(qiáng)制類型轉(zhuǎn)換轩勘。
as?和as怯邪!操作符的轉(zhuǎn)換規(guī)則完全一樣绊寻,但是as?會(huì)返回一個(gè)被轉(zhuǎn)換類型的可選類型,需要我們解封澄步。因此寫法會(huì)略有不同冰蘑,
Swift—使用try?和try!區(qū)別
**1.使用try? **
try?會(huì)將錯(cuò)誤轉(zhuǎn)換為可選值,當(dāng)調(diào)用try?+函數(shù)或方法語句時(shí)候村缸,如果函數(shù)或方法拋出錯(cuò)誤祠肥,程序不會(huì)發(fā)崩潰,而返回一個(gè)nil梯皿,如果沒有拋出錯(cuò)誤則返回可選值仇箱。
2.使用****try!
使用try!可以打破錯(cuò)誤傳播鏈條。錯(cuò)誤拋出后傳播給它的調(diào)用者东羹,這樣就形成了一個(gè)傳播鏈條剂桥,但有的時(shí)候確實(shí)不想讓錯(cuò)誤傳播下去,可以使用try!語句属提。
AnyObject是一定不能為空权逗,包括初始化的時(shí)候
AnyObject!表示類型是一個(gè)optional類型冤议,初始化的時(shí)候可以為空斟薇,但是加!表示知道用它時(shí)它是一定不為空的
Swift 語言中 類型后面的 恕酸?和 堪滨! 有什么作用?
! 并不代表一定有值. 在定義一個(gè)屬性的時(shí)候使用 ! , 那么你在取值或賦值的時(shí)候就不需要手動(dòng)強(qiáng)制解包了.但是如果定義的時(shí)候?qū)?, 在賦值/取值的時(shí)候就需要自己解包
Swift語言使用var定義變量蕊温,但和別的語言不同袱箱,Swift里不會(huì)自動(dòng)給變量賦初始值,
也就是說變量不會(huì)有默認(rèn)值寿弱,所以要求使用變量之前必須要對(duì)其初始化
犯眠。如果在使用變量之前不進(jìn)行初始化就會(huì)報(bào)錯(cuò):
var stringValue : String
//error: variable 'stringValue' used before being initialized
//let hashValue = stringValue.hashValue
// ^
let hashValue = stringValue.hashValue
出錯(cuò)的原因就是在使用stringValue這個(gè)變量之前按灶,沒有初始化這個(gè)變量症革,也就是這個(gè)變量根本就沒有得到內(nèi)存,
這時(shí)就會(huì)出錯(cuò)鸯旁。
那么我們可以使用optional類型噪矛,后面跟一個(gè)?就是了铺罢。
// 這就是optional, strValue自動(dòng)得到默認(rèn)值:nil
// 這個(gè)nil跟Objective-C中的nil不同艇挨,不是指針,而是表示值不存在韭赘。
var strValue: String?
// 判斷optional是否有值
if strValue {
// do what you need to do here
}
文檔中有提到說缩滨,在使用Optional值的時(shí)候需要在具體的操作,比如調(diào)用方法、屬性脉漏、下標(biāo)索引等前面需要加上一個(gè)苞冯?,如果是nil值(不存在值)侧巨,也就是Optional.None舅锄,會(huì)跳過后面的操作不執(zhí)行,如果有值司忱,就是Optional.Some可能就會(huì)拆包(unwrap)皇忿,然后對(duì)拆包后的值執(zhí)行后面的操作,來保證執(zhí)行這個(gè)操作的安全性坦仍,比如Optional binding:
// optional binding
// 如果strValue == nil, 那么結(jié)果就是nil,不會(huì)調(diào)用String的hasValue
// 如果strValue != nil, 就返回strValue對(duì)應(yīng)的hashValue值并賦值給常量hashValue
if let hashValue = strValue?.hashValue {
// do something if neccessary
}
在寫協(xié)議(protocol)時(shí)鳍烁,對(duì)于可選代理方法,也需要在調(diào)用時(shí)在函數(shù)名后跟著桨踪?,如:
// @objc 是用于處理Swift與OC之間的轉(zhuǎn)換的老翘,由于@optional是OC中的關(guān)鍵字,
// 所以在protocol之前需要添加上@objc锻离。
@objc protocol HttpRequestDelegate {
// @optional 說明這個(gè)代理方法是可選方法铺峭,
// 那么在調(diào)用的時(shí)候,需要這樣調(diào)用:delegate?.requestFinished?(self, downloadData)
// 其中delegate?是因?yàn)閐elegate也是optional的
@optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)
// other funcs ...
}
var delegate: HttpRequestDelegate?
var downloadData = NSMutableData()
delegate.requestFinished(self, downloadData)
當(dāng)然我們也可以使用汽纠!來強(qiáng)制拆包卫键,這是我們?cè)诒WC有值的情況下才會(huì)這么用:
var strValue: String?
strValue = "1234"
let integer = strValue!.toInt()
// 更安全的寫法是
if strValue {
let integer = strValue!.toInt()
}
隱式強(qiáng)拆包類型:使用!來聲明變量虱朵,會(huì)成為隱式強(qiáng)拆包可選類型莉炉,這表示這個(gè)類型永遠(yuǎn)不會(huì)出現(xiàn)nil的情況,但一旦出來碴犬,
在調(diào)用時(shí)就會(huì)崩潰絮宁。
// Implicitly Unwrapped Optionals
// 使用這種方式聲明的話,在調(diào)用時(shí)不需要使用?或服协!來說明绍昂。
var myLabel: UILabel!
myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))
myLabel.text = "label"
總結(jié):
通常在什么情況下才會(huì)使用optional類型呢?
(1)當(dāng)我們需要聲明這樣一個(gè)變量偿荷,變量在設(shè)計(jì)初始化函數(shù)中沒有進(jìn)行初始化時(shí)窘游,就需要聲明這個(gè)變量為optional類型。因?yàn)樽兞吭谑褂们氨仨毾?br>
聲明跳纳,并且在設(shè)計(jì)初始化函數(shù)中進(jìn)行初始化忍饰。比如我們?cè)趘iewDidLoad函數(shù)中才進(jìn)行初始化的控件(類成員),就需要聲明為optional且必須是var聲明寺庄,
因?yàn)閘et聲明的常量只能是在初始化函數(shù)中進(jìn)行初始化艾蓝。
(2)當(dāng)我們不知道是否會(huì)有值的時(shí)候力崇,這個(gè)變量可以聲明為optional,比如代理,我們并沒有要求必須傳代理過來赢织,那么就需要聲明為optional餐曹。
(3)作為函數(shù)參數(shù)時(shí),如果這個(gè)參數(shù)可以沒有值敌厘,那么就使用optional類型台猴,比如傳代理的時(shí)候,通常就是可選的俱两,可以設(shè)置為nil
var evalList = [Evakmodel]() //數(shù)組
var vrstore = Storemodel() //函數(shù)
var web view = UIWebView() //初始化方法
var topbtn:UIImafeView! //解包