Swift Closure

Tran Quan viết ngày 06/01/2018


What is closure?

Closures are self-contained blocks of functinality that can be PASSED around and USED in your code

-> Closure is a 1st class Object

Closures can CAPTURE and STORE REFERENCES to any constants and variables from the CONTEXT which they ayre defined

-> by reference mean not value, means, If we change any thing inside the closure, the object outsite the closure will also be affected

Closures are Reference Types

-> If I assign a cloure to two var, they actually refer to the same closure

Escape vs Non-Escaping

escape: mean the close will be STORED somewhere to execute later (and of course, its context also being STORED and this is the main reason cause retain cycles). Usually meet as api call

DispatchQueue.main.async {

non-escape: the close will be execute and return immediately, not being store, this is the trivia case. Usually meet when use a function in a collection:

[1,2,3].forEach { number in

If a closure is a property, It's auto escaping

// declare a callback being call a user is picked
var onUserPick: ((_ user: User) -> Void)?

Capture Values

  • Values are capture when being ACCESS (RUN)
var value = 1
let checkValue = { () -> Void in 
  print("value in closure: \(value)") // 2, not 1, because we change value before call
  value = 3 // change to three
value = 2 // change value affect in closure because I don't pass it in captures list
print("value before closure: \(value)") // 2: trivia, value has been changed
print("value after closure: \(value)") // 3: value is updated inside the closure

So the whole life cycle of value: 1 -> 2 -> 3

  • If using captures list the values are capture/copy when being PASSED (DEFINITION)
var value = 1
let checkValue = { [copyOfValue = value] () -> Void in 
  print("value in closure: \(copyOfValue)") // 1: because it has been copy at passing time
  // copyOfValue = 3 // cannot change value of parameter
value = 2 // change value is NOT affect in closure, because I used captures list
print("value before closure: \(value)") // 2: trivia, value has been changed
print("value after closure: \(value)") // 2: pass by value, not effect in closure

So the whole life cycle of value: 1 -> 1(copied) -> 2 -> 2

  • If the value is an Object, value is always pass by references whethe using captures list or not because object always a pointer
var user = User(name: "Kenji")
let checkValue = { [copyOfUser = user] () -> Void in
  print("value in closure \(copyOfUser.name)"); //  Shinja
  copyOfUser.name = "Otomo" // can change the props of object
user.name = "Shinja"
print("value before call closure \(user.name)") // Shinja
print("value after after call closure \(user.name)") // Otomo

Trailing Closure

Just a convenient way to write closure when it is the last argument in a function. When call that function, you can open parenthesis at the end (that why it is called trailing)

// define
func foo(closure: () -> Void) {
  ... foo body
// calling
foo(closure: {
  ... closure body
Bình luận

{{ comment.user.name }}
Bỏ hay Hay
Male avatar
{{ comment_error }}

Hiển thị thử

Chỉnh sửa


Tran Quan

1 bài viết.
0 người follow
{{userFollowed ? 'Following' : 'Follow'}}
Bài viết liên quan
14 4
(Link) (Link) (Link) Ở 2 phần tut trước, mình đã hướng dẫn khá chi tiết cách viết một ứng dụng camera có tích hợp chức năng nhận diện khuôn mặ...
HoangPH viết gần 6 năm trước
14 4
2 0
Có nhiều cách viết blog công nghệ hơn là làm bánh hay làm tình. Những ngày này Hà Nội mưa liên miên, được cái mát giời, mình lại tức cảnh sinh tìn...
VietHQ viết gần 4 năm trước
2 0
0 0
Swift là ngôn ngữ do Apple tạo ra và nhận được sử ủng hộ lớn từ cộng đồng. Nhất là từ khi nó opensource. Bản thân ngôn ngữ vẫn đang ngày một hoàn t...
VietHQ viết hơn 2 năm trước
0 0


{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}

{{userFollowed ? 'Following' : 'Follow'}}
1 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!