Swift - closure(闭包)

闭包是一个在上下文中闭合的独立的函数代码块,可以在代码中被传递和使用。swift中的闭包与OC中的block相似,并且更强大,可以作为参数传递给函数。

语法

{(parameters) -> return type in
   code
}
  • parameters:请求参数
  • return type: 返回值类型
  • in:分割返回值类型和代码块的关键字
  • code:代码块

闭包的简化

1.没有请求参数的闭包,可以省略in

let closure1 = {()
   print("hh")
}

2.没有请求参数的闭包,可以省略(),同时必须省略in

let closure1 = {
   print("hh")
}

3.闭包内表达式只有一行,可以省略return

let closure4 = {(a: Int, b: Int) in
   a+b
}

4.使用简化参数名,0,1(从0开始,表示第i个参数...)

let numArr = [5, 1, 4, 2, 7]
let newArr = numArr.sorted(by: {$0 > $1})
print(newArr)

5.闭包作为函数最后一个参数(尾随闭包),将闭包写在()

定义函数:

func getString(str1: String, str2: String, closure:(String, String) -> String) -> String {
  return closure(str1, str2)
}

省略前:

let appendStrClosure = { (str1: String, str2: String) in
  return str1 + str2
}
let newStr = getString(str1: "字符串1", str2: "字符串2", closure: appendStrClosure)
print("函数执行结果:", newStr)

省略为

let newStr1_1 = getString(str1: "字符串1", str2: "字符串2") {
  return $0 + $1
}

6. 闭包作为函数的唯一参数,可以省略()

定义函数:

func closureFunc(closure: () -> Void) -> Void {
  closure()
}

调用函数:

closureFunc {
  print("closure执行完毕")
}

特点:

  1. 值捕获:
    闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
  2. 引用类型:
    将函数或闭包赋值给一个常量或者变量,实际上都是将常量或变量的值设置为对应函数或闭包的引用

闭包的类型

1.无参 无返回值

  • 声明
let closure1 = {
  print("hh")
}
  • 调用
closure1()

2.无参 有返回值

  • 声明
let closure2 = {
  return "哈哈"
}
  • 调用
print(closure2())

3.有参 无返回值

  • 声明
let closure3 = {(a: String) in
  print(a)
}
  • 调用
closure3("zz")

4.有参 有返回值

  • 声明
let closure4 = {(a: Int, b: Int) in
  return a+b
}
  • 调用
print(closure4(1, 2))

特殊的闭包

1.尾随闭包

闭包作为函数的最后一个参数,函数调用的时候可以将闭包写在()后面,称为尾随闭包

  • 函数声明
func getString(str1: String, str2: String, closure:(String, String) -> String) -> String {
  return closure(str1, str2)
}
  • 函数调用
let newStr1_1 = getString(str1: "字符串1", str2: "字符串2") {
  return $0 + $1
}

2.逃逸闭包

当闭包作为一个参数传递给一个函数,并能在函数执行结束后调用,就说这个闭包逃逸了。
声明函数时,闭包的形参前用@escaping修饰,来表示这是一个逃逸闭包,对开发者也是一个警示作用。

  • 函数声明:
var result: ()->Void = {}
var string = ""
func showFunc(closure: @escaping () -> Void) {
  result = closure//2
}
  • 函数调用:
showFunc {self.string = "逃逸闭包"}//1
print(string)//3
result()//4
print(string)//5
  • 分步理解:
  1. 调用函数,传入一个闭包;
  2. 函数内,将传入的闭包赋给result后,函数执行结束;
  3. 打印字符串,此时闭包还没调用;
  4. 调用result闭包;
  5. 调用result后再次打印,此时闭包才调用。

页面间传值

  1. typealias为闭包类型起别名
  2. 声明一个变量,类型为别名。
typealias voidClosure = (String) -> Void
var closure : voidClosure?
  1. 在触发传值的位置调用闭包
if closure != nil {
  self.closure!("Did Add")
  self.navigationController?.popViewController(animated: true)
}
  1. 在上级页面,实现闭包
vc.closure = { string in
  print(string)
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Closure 的定义网上也比较多比较全,下面所写不会具体介绍语法,只做简单归纳、实例阐述。 一、归纳属性闭包 1...
    木叔勒阅读 4,130评论 0 0
  • 究竟什么是Closure? 说的通俗一点,一个函数加上它捕获的变量一起,才算一个closure //MARK: -...
    AKyS佐毅阅读 3,486评论 1 1
  • 一:闭包表达式 1:闭包类似匿名函数 1: 闭包类似匿名函数2: 当一个函数的参数是闭包时,可以传入一个函数名,函...
    __Simon__阅读 1,774评论 0 0
  • 闭包基础 ** 闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objecti...
    Michael杨阅读 2,607评论 1 2
  • 前言:swift是一门很优雅,很简洁,功能很强大的语言,同时也是一门很复杂的语言。进门比较简单,看完苹果官方的文档...
    一剑孤城阅读 11,369评论 0 10