美文网首页
Swift中的Closure

Swift中的Closure

作者: 晓先生ol | 来源:发表于2020-03-27 12:38 被阅读0次

结论:

  • Swift closures capture a reference to the outer variables that you happen to use inside the closure. Swift闭包默认对外部变量捕获其引用
  • That reference gets evaluated at the time the closure itself gets executed. 该引用在闭包执行的时候计算(读取值)
  • Being a capture of the reference to the variable (and not the variable’s value itself), you can modify the variable’s value from within the closure (if that variable is declared as var and not let, of course) 捕获引用后可以在闭包内部修改变量的值,当然前提得是var而不是let的
  • You can instead tell Swift to evaluate a variable at the point of the closure creation and store that value in a local constant, instead of capturing the variable itself. You do that using capture lists expressed inside brackets. 可以通过捕获列表(capture list)来告诉Swift捕获变量的内容而不是变量本身(引用)

--《Closures Capture Semantics: Catch them all!

class Pokemon: CustomDebugStringConvertible {
    let name: String
    init(name: String) {
        self.name = name
    }
    var debugDescription: String { return "<Pokemon \(name)>" }
    deinit { print("\(self) deinit...!") }
}

func delay(_ seconds: Int, closure: @escaping ()->()) {
    let time = DispatchTime.now() + .seconds(seconds)
    DispatchQueue.main.asyncAfter(deadline: time) {
        print("")
        closure()
    }
}
var pokemon = Pokemon(name: "Pikachu") //如果这里用var而非let的话,在闭包内部可以修改变量的值,但这并不影响下面Swift的捕获规则
print("before closure: \(pokemon)")
delay(1) {
    print("inside closure: \(pokemon)")
    //Swift captures variables by reference by default. Swift默认情况下通过引用捕获变量,且默认为strong强引用,目的是pokenmon在Closure被调用时还存在
    //Swift并不是捕获“Pikachu”,而是pokemon变量,所以执行闭包Closure时得到的是“Mewtwo”
}
pokemon = Pokemon(name: "Mewtwo")
print("after closure: \(pokemon)")
/*
 before closure: <Pokemon Pikachu>
 <Pokemon Pikachu> deinit...!
 after closure: <Pokemon Mewtwo>
 
 inside closure: <Pokemon Mewtwo>
 <Pokemon Mewtwo> deinit...!
 */
//this works for value types too, like Int. 这也同样适用于值类型,如Int。
var value = 2
print("before closure: \(value)")
delay(1) {
    print("inside closure: \(value)")
    //it captures a reference to the variable(still refers to the same variable), not the variable content itself. 捕获的是对变量的引用而非变量内容。
}
value = 3
print("after closure: \(value)")
/*
before closure: 2
after closure: 3

inside closure: 3
*/

In Swift, Array, String, and Dictionary are all value types. They behave much like a simple int value in C, acting as a unique instance of that data. see Value and Reference Types. 在Swift里,Array、String、Dictionary都是值类型,它们就像Int一样,作为唯一的数据实例。

//Capturing a variable as a constant copy(the content of the value variable at the time of creation.),you can use a capture list.通过捕获列表捕获变量内容而不是其引用,这种方法同样适用于引用类型(reference type),如上面的Pokemon。
var aInt = 1
var bInt = 5
print("init: aInt=\(aInt);bInt=\(bInt)")
delay(1) { [a = aInt, b = bInt] in
    print("closure: a=\(a);b=\(b)")
}
aInt += 1
bInt += 1
print("modified: aInt=\(aInt);bInt=\(bInt)")
/*
 init: aInt=1;bInt=5
 modified: aInt=2;bInt=6
 
 closure: a=1;b=5
 */



var aPoke = Pokemon(name: "A")
var bPoke = Pokemon(name: "B")
print("init: aPoke=\(aPoke);bPoke=\(bPoke)")
delay(1) { [a = aPoke, b = bPoke] in
    print("closure: a=\(a);b=\(b)")
}
aPoke = Pokemon(name: "AA")
bPoke = Pokemon(name: "BB")
print("modified: aPoke=\(aPoke);bPoke=\(bPoke)")
/*
 init: aPoke=<Pokemon A>;bPoke=<Pokemon B>
 modified: aPoke=<Pokemon AA>;bPoke=<Pokemon BB>
 <Pokemon BB> deinit...!
 <Pokemon AA> deinit...!
 
 closure: a=<Pokemon A>;b=<Pokemon B>
 <Pokemon A> deinit...!
 <Pokemon B> deinit...!
 */

//等同于↓:
let aPoke = Pokemon(name: "A")
let bPoke = Pokemon(name: "B")
print("init: aPoke=\(aPoke);bPoke=\(bPoke)")
delay(1) {
    print("closure: a=\(aPoke);b=\(bPoke)")
}

参考资料:

相关文章

  • 十二月第三周

    1.swift中closure与OC中block的区别?1>、closure是匿名函数、block是一个结构体对象...

  • Swift中的Closure

    结论:Swift closures capture a reference to the outer variab...

  • Swift学习笔记

    swift学习笔记01: “一等公民“ func & closure 先来几个函数: 在swift中,我们可以这样...

  • (十三) [Swift]Swift中的Closure

    1.完整的定义一个closure 省略参数类型 单语句closure可以省略return 终极简化,将参数用$1,...

  • 《Using Swift with Cocoa and Obje

    Swift 中的 Closure 与 Objective-C 中的 Block 有一个显著的区别,就是 Closu...

  • Swift 中 Closure 闭包 和 Objective

    一 前言: Swift 中的 Closure 和 Objective-C 中的Block 都是非常常用 的语法。本...

  • swift closure

    官方https://developer.apple.com/library/content/documentati...

  • Closure in Swift

    跟Block很像,表示代码的集合,简称代码块。 可以被传递,不会马上被执行,当然后期可以被执行多次。 NSURLS...

  • Swift Closure

    Closure是自包含的代码块,可以在代码中传递和使用,类似于OC中的Block。Closure可以捕获或者存储定...

  • Swift中的闭包详解

    转载自:Swift中的闭包(Closure) 概念 闭包在Swift中非常有用。通俗的解释就是一个Int类型里存储...

网友评论

      本文标题:Swift中的Closure

      本文链接:https://www.haomeiwen.com/subject/tfcluhtx.html