Swift2.0中加入了defer新语法声明。defer译为延缓、推迟之意。那么在Swift2.0中它将被应用于什么位置呢?比如,读取某目录下的文件内容并处理数据,你需要首先定位到文件目录,打开文件夹,读取文件内容以及处理数据,关闭文件以及文件夹。倘若一切顺利,只需按照设定好的程序流程走一轮即可;不过考虑事情要面面俱到,倘若中间某个环节失败,比如读取文件内容失败、处理数据失败等等,还需要进行一些后续收尾工作,即关闭文件或关闭文件夹(当然就算顺利执行,也是要关闭的)。
先谈谈defer的基础语法,声明方式如下:
defer{// 做一些事情}
可以看到声明方式非常简单,defer关键字打头,紧跟{}程序块,大括号中添加延迟处理代码。平常应用方式如下:
funcdoSomethingWithDefer(){// 1openDirectory()// 2defer{closeDirectory()}// 3openFile()// 4defer{closeFile()}// 做其他杂七杂八事情...}
分析代码:
定位到目录并打开指定文件夹,倘若打开文件夹失败则结束函数。
主要到defer的用法,这条语句并不会马上执行,而是被推入栈中,直到函数结束时才再次被调用。
打开文件,倘若失败则结束函数。
defer内容关闭文件,这条语句一样不会被马上执行,而是推入栈中,此时它位于defer{closeDirectory()}语句的上方,直到函数结束时才再次被调用。
倘若一切都顺利,函数运行到最后了,开始从栈中依次弹出方才推入的defer语句,首先是closeFile(),其次是closeDirectory()。确实当我们处理完文件,需要先关闭文件,再关闭文件夹。
现在试想一种情况,我们已经打开文件夹,并且推closeDirectory()到栈中,执行第三步openFile()操作的时候出错了!那么下面所有操作就无法进行下去,结束整个函数了!前文说到函数结束时开始执行defer栈中的内容,关闭文件夹。会有人说怎么不关闭文件,拜托失败了就意味着文件没被打开,何来关闭一说。
最后必须说下defer的作用域,这点灰常重要。
注意作用域,其次是调用顺序——即一个作用域结束,该作用域中的defer语句自下而上调用。
funclookforSomething(name:String)throws{//这里是作用域1 整个函数作用域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("")//调出 debug Area 快捷键 shift+ command + ytry! lookforSomething("hello")
其实先前有个地方说的不准确,并不是函数结束时开始执行defer栈推出操作,而是每当一个作用域结束就进行该作用域defer执行。