標籤:調用 處理 some on() point bdd java 方法 status
1、Defer
在一些語言中,有 try/finally 這樣的控制語句,比如 Java。這種語句可以讓我們在 finally 代碼塊中執行必須要執行的代碼,不管之前怎樣的興風作浪。在 Swift 2.0 中,Apple 提供了 defer 關鍵字,讓我們可以實現同樣的效果。
func checkSomething() { print("CheckPoint 1") doSomething() print("CheckPoint 4")}func doSomething() { print("CheckPoint 2") defer { print("Clean up here") } print("CheckPoint 3")}// CheckPoint 1, CheckPoint 2, CheckPoint 3, Clean up here, CheckPoint 4checkSomething()
- 上述樣本可以看到,在列印出
CheckPoint 2 之後並沒有列印出 Clean up here,而是 CheckPoint 3,這就是 defer 的作用,它對進行了 print("Clean up here") 延遲。
在你的代碼塊就要結束前。如果你使用了 defer。在其之中的代碼就會運行。等於說,給了你最後的機會來進行一些處理。如果你熟悉 BDD 或者 TDD,那麼你可以參考他們中的 aferAll 機制。
func myFunction() throws { defer { // No matter what happened I need do something print("All done, clean up here") } guard let item = item else { // need throws the error out throw MyError.notExist } guard item.count > maxNumber else { // need throws the error out throw MyError.outOfRange } // do something with item // ...}
如果你有多個 defer 語句,他們在執行的順序會和棧一樣,最後一個進,第一個出。
2、Defer 樣本
我們再來看一個 I/O 的樣本
func writeSomething() { let file = OpenFile() let ioStatus = fetchIOStatus() guard ioStatus != "error" else { return } file.write() closeFile(file)}
- 上述樣本是一個 I/O 操作的虛擬碼,如果擷取到的
ioStatus 正常,那麼該方法沒有問題,如果 ioStatus 取到的是 error,那麼會被 guard 語句抓到執行 return 操作,這樣的話 closeFile(file) 就永遠都不會執行了,一個嚴重的 Bug 就這樣產生了。
下面我們看看如何用 defer 來解決這個問題。
func writeSomething() { let file = OpenFile() defer { closeFile(file) } let ioStatus = fetchIOStatus() guard ioStatus != "error" else { return } file.write()}
- 我們將
closeFile(file) 放在 defer 代碼塊裡,這樣即使 ioStatus 為 error,在執行 return 前會先執行 defer 裡的代碼,這樣就保證了不管發生什麼,最後都會將檔案關閉。
Swift Defer 延遲調用