Swift2.0中加入了defer新語(yǔ)法聲明。defer譯為延緩、推遲之意。那么在Swift2.0中它將被應(yīng)用于什么位置呢?比如,讀取某目錄下的文件內(nèi)容并處理數(shù)據(jù),你需要首先定位到文件目錄,打開文件夾,讀取文件內(nèi)容以及處理數(shù)據(jù),關(guān)閉文件以及文件夾。倘若一切順利,只需按照設(shè)定好的程序流程走一輪即可;不過(guò)考慮事情要面面俱到,倘若中間某個(gè)環(huán)節(jié)失敗,比如讀取文件內(nèi)容失敗、處理數(shù)據(jù)失敗等等,還需要進(jìn)行一些后續(xù)收尾工作,即關(guān)閉文件或關(guān)閉文件夾(當(dāng)然就算順利執(zhí)行,也是要關(guān)閉的)。
先談?wù)刣efer的基礎(chǔ)語(yǔ)法,聲明方式如下:
defer{// 做一些事情}
可以看到聲明方式非常簡(jiǎn)單,defer關(guān)鍵字打頭,緊跟{}程序塊,大括號(hào)中添加延遲處理代碼。平常應(yīng)用方式如下:
funcdoSomethingWithDefer(){// 1openDirectory()// 2defer{closeDirectory()}// 3openFile()// 4defer{closeFile()}// 做其他雜七雜八事情...}
分析代碼:
定位到目錄并打開指定文件夾,倘若打開文件夾失敗則結(jié)束函數(shù)。
主要到defer的用法,這條語(yǔ)句并不會(huì)馬上執(zhí)行,而是被推入棧中,直到函數(shù)結(jié)束時(shí)才再次被調(diào)用。
打開文件,倘若失敗則結(jié)束函數(shù)。
defer內(nèi)容關(guān)閉文件,這條語(yǔ)句一樣不會(huì)被馬上執(zhí)行,而是推入棧中,此時(shí)它位于defer{closeDirectory()}語(yǔ)句的上方,直到函數(shù)結(jié)束時(shí)才再次被調(diào)用。
倘若一切都順利,函數(shù)運(yùn)行到最后了,開始從棧中依次彈出方才推入的defer語(yǔ)句,首先是closeFile(),其次是closeDirectory()。確實(shí)當(dāng)我們處理完文件,需要先關(guān)閉文件,再關(guān)閉文件夾。
現(xiàn)在試想一種情況,我們已經(jīng)打開文件夾,并且推closeDirectory()到棧中,執(zhí)行第三步openFile()操作的時(shí)候出錯(cuò)了!那么下面所有操作就無(wú)法進(jìn)行下去,結(jié)束整個(gè)函數(shù)了!前文說(shuō)到函數(shù)結(jié)束時(shí)開始執(zhí)行defer棧中的內(nèi)容,關(guān)閉文件夾。會(huì)有人說(shuō)怎么不關(guān)閉文件,拜托失敗了就意味著文件沒(méi)被打開,何來(lái)關(guān)閉一說(shuō)。
最后必須說(shuō)下defer的作用域,這點(diǎn)灰常重要。
注意作用域,其次是調(diào)用順序——即一個(gè)作用域結(jié)束,該作用域中的defer語(yǔ)句自下而上調(diào)用。
funclookforSomething(name:String)throws{//這里是作用域1 整個(gè)函數(shù)作用域print("1-1")ifname ==""{//這里是作用域2 if的作用域print("2-1")defer{print("2-2")? ? }print("2-3")? }print("1-2")defer{print("1-3")? }print("1-4")ifname =="hello"{//作用域3print("3-1")defer{print("3-2")? ? }print("3-3")defer{print("3-4")? ? }? }}//有興趣的看看依次輸出什么//try! lookforSomething("")//調(diào)出 debug Area 快捷鍵 shift+ command + ytry! lookforSomething("hello")
其實(shí)先前有個(gè)地方說(shuō)的不準(zhǔn)確,并不是函數(shù)結(jié)束時(shí)開始執(zhí)行defer棧推出操作,而是每當(dāng)一個(gè)作用域結(jié)束就進(jìn)行該作用域defer執(zhí)行。