Swift Closure
swift
45
Closure
2
White

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

Documents

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
checkValue()
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
checkValue()
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
checkValue();
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


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Tran Quan

1 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Bài viết liên quan
White
23 3
Chào mừng sự trở lại sau kì nghỉ, đây cũng là bài viết cuối cùng trong năm 2015 của tôi. Trong bài viết này tôi sẽ giới thiệu với các bạn về Closur...
Hoàng Nguyễn viết 2 năm trước
23 3
{{like_count}}

kipalog

{{ comment_count }}

bình luận

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


White
{{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á!