1. 程式人生 > >Swift基礎2.1——閉包

Swift基礎2.1——閉包

在之前一篇關於block的總結中,也提到過,閉包與 OC 中的 Block 類似,閉包主要用於非同步操作執行完成後的程式碼回撥,網路訪問結果以引數的形式傳遞給呼叫方。

閉包的定義

  • 定義一個閉包
    • 閉包 = { (行參) -> 返回值 in // 程式碼實現 }
    • in 用於區分函式定義和程式碼實現
//: 閉包 = { (行參) -> 返回值 in // 程式碼實現 }
let sumFunc = { (num1 x: Int, num2 y: Int) -> Int in
    return x + y
}
sumFunc(num1: 10, num2: 20)
  • 閉包格式小結
// 格式: let 閉包名: (形參) -> 返回型別 = { (形參1, 形參2, ...) in 程式碼實現 }
// 說明: 使用形參列表,可以直接提供外部引數 // // 格式: let 閉包名: (形參型別) -> 返回型別 = { (形參1, 形參2, ...) in 程式碼實現 } // // 格式: { (外部引數1 形參1, 外部引數2 形參2, ...) -> 返回型別 in 程式碼實現 } // 說明: 使用外部引數會方便呼叫 // // 格式: { (形參列表) -> 返回型別 in 程式碼實現 }
最簡單的閉包,如果沒有引數/返回值,則 引數/返回值/in 統統都可以省略
let demoFunc = {
    print("hello")
}

基本使用

GCD 非同步

  • 模擬在後臺執行緒載入資料
func loadData() {
    dispatch_async(dispatch_get_global_queue(0, 0), { () -> Void in
        print("耗時操作 \(NSThread .currentThread())")
    })
}
  • 尾隨閉包,如果閉包是最後一個引數,可以用以下寫法
  • 注意上下兩段程式碼,} 的位置
func loadData() {
    dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
        print("耗時操作 \(NSThread .currentThread()
)"
) } }
  • 閉包的簡寫,如果閉包中沒有引數和返回值,可以省略
func loadData() {
    dispatch_async(dispatch_get_global_queue(0, 0)) {
        print("耗時操作 \(NSThread .currentThread())")
    }
}

自定義閉包引數,實現主執行緒回撥

  • 新增沒有引數,沒有返回值的閉包
override func viewDidLoad() {
    super.viewDidLoad()

    loadData {
        print("完成回撥")
    }
}

// MARK: - 自定義閉包引數
func loadData(finished: ()->()) {

    dispatch_async(dispatch_get_global_queue(0, 0)) {
        print("耗時操作 \(NSThread.currentThread())")

        dispatch_sync(dispatch_get_main_queue()) {
            print("主執行緒回撥 \(NSThread.currentThread())")

            // 執行回撥
            finished()
        }
    }
}
  • 添加回調引數
override func viewDidLoad() {
    super.viewDidLoad()

    loadData4 { (html) -> () in
        print(html)
    }
}

/// 載入資料
/// 完成回撥 - 傳入回撥閉包,接收非同步執行的結果
func loadData4(finished: (html: String) -> ()) {

    dispatch_async(dispatch_get_global_queue(0, 0)) {
        print("載入資料 \(NSThread.currentThread())")

        dispatch_sync(dispatch_get_main_queue()) {
            print("完成回撥 \(NSThread.currentThread())")

            finished(html: "<h1>hello world</h1>")
        }
    }
}

關於閉包的迴圈引用,與block完全一致,在另一篇部落格中有介紹。具體參看下屬連結。