Skip to content

Instantly share code, notes, and snippets.

@colourful987
Last active September 16, 2016 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colourful987/148d367f2c4f84f8fe9b30e0441d8f90 to your computer and use it in GitHub Desktop.
Save colourful987/148d367f2c4f84f8fe9b30e0441d8f90 to your computer and use it in GitHub Desktop.
Seven Demo For Explaining Swift Closures Capture Semantics
//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
class Pokemon :CustomStringConvertible{
let name: String
init(name:String) {
self.name = name
}
var description:String{return "<Pokemon \(name)>"}
deinit {
print("\(self) escaped")
}
}
func delay(seconds: Int, closure: @escaping ()->()) {
let time = DispatchTime.now() + .seconds(seconds)
DispatchQueue.main.asyncAfter(deadline: time) {
print("🕑")
closure()
}
}
//: 关于GCD的知识,请点击[这里](http://www.jianshu.com/p/8cb4f395d2c4)
func demo1() {
let pokemon = Pokemon(name: "Mewtwo")
print("before closure: \(pokemon)")
delay(seconds: 1) {// 由于delay函数使用了异步方式 所以不会阻塞当前线程 而是立即执行之后的print bye
print("inside closure: \(pokemon)")
}
print("bye")
}
func demo2() {
var pokemon = Pokemon(name: "Pikachu")
print("before closure: \(pokemon)") // 1.目前皮卡丘
delay(seconds: 1) {
print("inside closure: \(pokemon)") // 4. 闭包拥有的是pokemon 指针 而不是内容
}
pokemon = Pokemon(name: "Mewtwo") // 2.精灵球捕获了超梦 却让皮卡丘释放了
print("after closure: \(pokemon)")// 3.此时精灵球里是超梦
}
func demo3() {
var value = 42
print("before closure: \(value)")
delay(seconds: 1) {
print("inside closure: \(value)")
}
value = 1337
print("after closure: \(value)")
}
func demo4() {
var value = 42
print("before closure: \(value)")
delay(seconds: 1) {
print("inside closure 1, before change: \(value)")
value = 1337
print("inside closure 1, after change: \(value)")
}
delay(seconds: 2) {
print("inside closure 2: \(value)")
}
}
func demo5() {
var value = 42
print("before closure: \(value)")
delay(seconds: 1) { [constValue = value] in
print("inside closure: \(constValue)")
}
value = 1337
print("after closure: \(value)")
}
func demo6() {
var pokemon = Pokemon(name: "Pikachu")
print("before closure: \(pokemon)")
delay(seconds: 1) { [pokemonCopy = pokemon] in
print("inside closure: \(pokemonCopy)")
}
pokemon = Pokemon(name: "Mewtwo")
print("after closure: \(pokemon)")
}
func demo6_equivalent() {
var pokemon = Pokemon(name: "Pikachu")
print("before closure: \(pokemon)")
// here we create an intermediate variable to hold the instance
// pointed by the variable at that point in the code:
let pokemonCopy = pokemon
delay(seconds: 1) {
print("inside closure: \(pokemonCopy)")
}
pokemon = Pokemon(name: "Mewtwo")
print("after closure: \(pokemon)")
}
func demo7() {
var pokemon = Pokemon(name: "Mew")
print("➡️ Initial pokemon is \(pokemon)")
delay(seconds: 1) { [capturedPokemon = pokemon] in
print("closure 1 — pokemon captured at creation time: \(capturedPokemon)")
print("closure 1 — variable evaluated at execution time: \(pokemon)")
pokemon = Pokemon(name: "Pikachu")
print("closure 1 - pokemon has been now set to \(pokemon)")
}
pokemon = Pokemon(name: "Mewtwo")
print("🔄 pokemon changed to \(pokemon)")
delay(seconds: 2) { [capturedPokemon = pokemon] in
print("closure 2 — pokemon captured at creation time: \(capturedPokemon)")
print("closure 2 — variable evaluated at execution time: \(pokemon)")
pokemon = Pokemon(name: "Charizard")
print("closure 2 - value has been now set to \(pokemon)")
}
}
// execute 例子想要说明的问题是 函数结束了 临时变量 pokemon 应该释放掉 实际不是的 因为我们的闭包对它有个retain操作
//demo1()
// 学习 Swift 在闭包执行时才会取出捕获变量的值 我们可以认为它之前捕获的是变量的引用
//demo2()
// 虽然是值类型 但是!还是引用
//demo3()
// 了解变量可以在闭包内修改
//demo4()
// 如果是在闭包创建时捕获 那么值copy 而不是引用
//demo5()
// demo5 是值类型创建闭包时copy 那么一个类呢?
//demo6()
//demo6_equivalent()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment