Tất cả các mục nhập trong danh sách chụp tạo ra một biến số địa phương trong trường hợp đóng cửa . Nó được khởi tạo với giá trị của biến số có cùng tên trong ngữ cảnh bên ngoài, nhưng có thể được sửa đổi một cách độc lập.
Trong trường hợp của bạn
var closure = { [weak a] in
a = Animal()
a?.stamina = 10
}
a
bên trong đóng cửa được khởi tạo với một tham chiếu yếu đến đối tượng Animal
tạo trước đó, nhưng nó không phụ thuộc vào bên ngoài a
biến. a = Animal()
tạo một phiên bản mới và gán tham chiếu cho biến cục bộ đó a
. Bởi vì nó là một tham chiếu yếu, đối tượng được deallocated ngay lập tức (bạn có thể xác minh rằng bằng cách thêm print(a)
trong đóng cửa). Biến ngoài a
vẫn tham chiếu đối tượng ban đầu:
print(a.stamina) // 0
a.increaseStamina()
print(a.stamina) // 1
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100a03060)
closure()
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100a03060)
print(a.stamina) // 1
Nếu bạn bỏ qua danh sách chụp sau đó a
bên trong đóng cửa và ngoài việc đóng cửa tham khảo các biến tương tự, và một trường hợp mới có thể được gán bên trong đóng cửa:
var a = Animal()
var closure = {
a = Animal()
a.stamina = 10
}
print(a.stamina) // 0
a.increaseStamina()
print(a.stamina) // 1
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100b06ac0)
closure()
print(ObjectIdentifier(a)) // ObjectIdentifier(0x0000000100e00070)
print(a.stamina) // 10
để biết thêm thông tin và chi tiết, xem "Capture Lists" trong tài liệu tham khảo Swift (nhờ vậy @Arthur cho việc cung cấp liên kết).
Nguồn
2016-09-13 09:06:19
Bản sao có thể có của [Làm cách nào để đóng các giá trị từ các cuộc gọi trước?] (Http://stackoverflow.com/questions/37839020/how-do-closures-capture-values-from-previous-calls) – Honey
@Honey: Tôi không chắc liệu điều đó có đủ điều kiện như một bản sao hay không. Nó có liên quan, nhưng không có danh sách chụp trong câu hỏi đó, và không có lớp học (loại tham chiếu). –
@MartinR Ohhhhk – Honey