Swift 4.2基礎 --- 捕獲列表(Capture Lists)

默認情況下,閉包表達式從其周圍範圍捕獲常量和變量,並對強引用這些值。可以使用捕獲列表顯式地控制如何在閉包中捕獲值。
捕獲列表是在參數列表之前,以逗號分隔的表達式列表,由方括號包圍。如果使用捕獲列表,則必須使用in關鍵字,即使省略了參數名、參數類型和返回類型。
在創建閉包時,將初始化捕獲列表中的條目。對於捕獲列表中的每個條目,一個常量被初始化爲周圍範圍中具有相同名稱的常量或變量的值。例如,在下面的代碼中,a包含在捕獲列表中,而b沒有,這給了它們不同的行爲。

var a = 0
var b = 0
let closure = { [a] in
    print(a, b)
}

a = 10
b = 10
closure()
// Prints "0 10"

有兩種不同的事物命名爲a,周圍範圍內的變量和閉包範圍內的常量,但只有一個名爲b的變量。當創建閉包時,內部作用域中的a使用外部作用域中的a值初始化,但它們的值不以任何特殊方式連接。 這意味着對閉包外a值的更改不會影響閉包內a的值,同時對閉包內a值的更改也不會影響閉包外a的值。 相比之下,在外部範圍中只有一個名爲b的變量,因此從閉包內或外的變化在這兩個地方都是可見的。
當捕獲的變量類型有引用語義時,則沒有這種區別。例如,下面的代碼中有兩個名爲x的事物,一個是外部作用域中的變量,另一個是內部作用域中的常量,但是由於引用語義,它們都引用同一個對象。

class SimpleClass {
    var value: Int = 0
}
var x = SimpleClass()
var y = SimpleClass()
let closure = { [x] in
    print(x.value, y.value)
}

如果表達式值的類型是一個類,您可以在捕獲列表中將表達式標記爲weakunowned,以捕獲對表達式值的weakunowned引用。

myFunction { print(self.title) }                    // implicit strong capture
myFunction { [self] in print(self.title) }          // explicit strong capture
myFunction { [weak self] in print(self!.title) }    // weak capture
myFunction { [unowned self] in print(self.title) }  // unowned capture

還可以將任意表達式綁定到捕獲列表中的指定值。 創建閉包時將計算表達式,並使用指定的強度捕獲值。 例如:

// Weak capture of "self.parent" as "parent"
myFunction { [weak parent = self.parent] in print(parent!.title) }

有關閉包表達式的更多信息和示例,請查看Closure Expressions
。有關捕獲列表的更多信息和示例,請查看 ARC中的解決閉包的強引用循環

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章