在测试中发现,defer
的block运行的顺序永远在他所在的函数的 最后一个
,也就是会在执行return
的上一个执行。不管你把defer
写到该函数的任何位置,他的block都会在return
的前一个
执行。
func deferTest() -> Int {
print("deferTest-->",1)
defer {
print("deferTest-->",2)
}
print("deferTest-->",3)
return 4
}
输出结果
deferTest--> 1
deferTest--> 3
deferTest--> 2
deferTest--> 4
我们来换个位置再试一次
func deferTest() -> Int {
defer {
print("deferTest-->",2)
}
print("deferTest-->",1)
print("deferTest-->",3)
return 4
}
输出结果
deferTest--> 1
deferTest--> 3
deferTest--> 2
deferTest--> 4
哪怕这个函数有多个return,在执行任意一个return之前,都会运行defer的block,前提是defer关键字的那一行代码已经运行。
func deferTest() -> Int {
defer {
print("deferTest-->",2)
}
print("deferTest-->",1)
print("deferTest-->",3)
if self.responds(to: #selector(test)) {
return 4
}else{
return 5
}
}
输出结果
deferTest--> 1
deferTest--> 3
deferTest--> 2
deferTest--> 4
func deferTest() -> Int {
defer {
print("deferTest-->",2)
}
print("deferTest-->",1)
print("deferTest-->",3)
//取反验证一下
if !self.responds(to: #selector(test)) {
return 4
}else{
return 5
}
}
输出结果
deferTest--> 1
deferTest--> 3
deferTest--> 2
deferTest--> 5
一个函数中有多个defer的时候,它是呈一个压栈状态的,也就是遵循后进先出的原则。
func deferTest() -> Int {
defer {
print("deferTest-->",1)
}
defer {
print("deferTest-->",2)
}
defer {
print("deferTest-->",3)
}
print("deferTest-->",4)
return 5
}
输出结果
deferTest--> 4
deferTest--> 3
deferTest--> 2
deferTest--> 1
deferTest--> 5
defer的应用场景
因为新接触的关键词,实际当中运用到的情况并不是很多,还有待继续在开发中发现。
目前我只在对数据库事物进行处理的时候用到了。在操作数据库的读写的时候加了一个线程锁有好几次都是只上锁但是忘记解锁,导致在下一次对数据库进行操作的时候由于未解锁而无法操作,虽然问题不大,但是排查起来相当困难。所以我在函数中加了一个defer
关键字,在其block中进行了lock.unlock()
。果然有效解决了我的烦恼。