Swiftで無名関数(クロージャ)の勘所(Swift2)

という名の自分用メモ



/// データ送信メソッド
/// 送信成功時と失敗時の処理は呼び出し側で定義する
func send(
        data text:String
        , didSendAction didSend:String -> Void
        , didErrorAction didError:String -> Void ) {
   // ...何か通信処理 
   if success {
     didSend("何かしらのレスポンスとか")
   }
   else {
     didError("何かエラーメッセージ")
   }
}

/// test という文字列を送信してみるという体で
func test() {
 
 // クロージャ メンバとして持たせるといったことも可能
    let didSend :String -> Void = {responsData in
        // 何か送信後の処理 レスポンスによって処理を変えるといったことを想定
        print("response:" + responsData)
    }
    
    send(data: "test",
         didSendAction: didSend,
         didErrorAction: { errMsg in print(errMsg) } ) // 直接も書ける
    
}
send() 関数で didSendAction と didErrorActionという クロージャを受けわたす関数を用意します。
それぞれのクロージャは文字列型の引数を一つ取ります。
送信成功時あるいは失敗時に呼び出し元から受け取ったクロージャで処理させるといったサンプルになります。


何が嬉しいかというと、この例では呼び出し側で送信が成功した時の処理、失敗した時の処理が定義できるので疎結合になって部品化が進むというところにあります。ただし作りをミスると使わない場合よりさらに可読性が悪くなります。


同じようなことを実現する方法としてデリゲートを使うという手もあります。
ただしクロージャを投げる方が可読性は高い印象(特に1つのデリゲートで複数処理を受け取る場合は途端に視認性が悪くなる)
NSURLConnection なんかはデリゲートを使ってます。


2016年10月4日火曜日