Swift 2.0 で追加された defer について
defer
deferは、Swift 2.0 で新たに追加された構文です。The Swift Programming Language: Statements
deferの動作
deferを使用すると、スコープを抜ける際に実行する処理を記述することができます。超簡単に例を示せば、次のようになります。
func f(){ defer{ print("2") } print("1") } // print "1" // print "2"
deferを複数定義した場合L.I.F.O.で処理されます。
func f(){ defer{ print(“1”) } defer{ print(“2”) } defer{ print(“3”) } } // print "3" // print "2" // print "1"
利用場所
「絶対的有効!」となるような場面がちょっと思いつかなかったのですが、一応例として
仮ですが、下記のような処理があったとして・・・
func MyFunc(){ // ストリームのオープン let st = NSOutputStream(toFileAtPath: path, append: false) st!.open() // ストーリームの使用 st!.write(&buffer, maxLength:100) st!.write(&buffer, maxLength:100) st!.write(&buffer, maxLength:100) // ストリームのクローズ st!.close() }
これが、条件による中断があるとなると、常にリソースの解放に注意が必要なります
func MyFunc(){ // ストリームのオープン let st = NSOutputStream(toFileAtPath: path, append: false) st!.open() st!.write(&buffer, maxLength:100) if !status { // 状態が変化していたら処理中断 st!.close() // ストリームのクローズ return } st!.write(&buffer, maxLength:100) if !status { // 状態が変化していたら処理中断 st!.close() // ストリームのクローズ return } st!.write(&buffer, maxLength:100) // ストリームのクローズ st!.close() }
そんな時は、リソースの確保と同時に、解放を書いておけばいいのでは無いでしょうか。
func MyFunc(){ // ストリームのオープン let st = NSOutputStream(toFileAtPath: path, append: false) st!.open() // オープンとセットでクローズ処理を書いてしまう defer{ st!.close() } st!.write(&buffer, maxLength:100) if !status { return } st!.write(&buffer, maxLength:100) if !status { return } st!.write(&buffer, maxLength:100) }
コードがスッキリするという意味ではなく、間違いが混入しにくくなるという意味で・・・
事後、条件分岐がより複雑になっても、リソース解放の処理に気を使う必要は無くなると思います。
ツッコミを恐れずに言ってしまうと、メソッドのデストラクタ?
「デストラクタ」・・・ちょっと懐かしい・・・
参考資料
https://medium.com/the-traveled-ios-developers-guide/swift-defer-bcef70de8767The defer keyword in Swift 2: try/finally done right – Hacking with Swift