Swift Closures | Swift 闭包

更新至Swift 3.0

基本语法

Closures 在 Swift 中的概念类似 C 和 Objective-C 中的 blocks 和其它语言中的 lambdas.

{ (参数) -> return type in
    表达式
}

举例:排序以下字符串数组

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

普通方法调用

func backwards(s1: String, _ s2: String) -> Bool {
    return s1 > s2
}
var reversed = names.sort(backwards)  // 系统提供的sort方法
// reversed 等于 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

将自定义 backwards 方法作为参数传入 sort(_:) 方法用于排序


闭包调用

reversed = names.sort({ (s1: String, s2: String) -> Bool in
    return s1 > s2
})
  • 闭包写法和普通方法的区别
  • 可以去掉 func 声明 和方法名, 将之后内容用 { } 包起来
  • 由于参数后的 { 通过上步骤挪到前面去了, in 这个关键字可表示闭包内容的开始
  • 其它照旧,这么短的方法可写成一行,简洁

根据 names 的 string 内容,和 sort 方法声明需要的参数
系统可自动推导出这个闭包的参数类型,所以可不写参数类型

reversed = names.sort( { s1, s2 in return s1 > s2 } )

闭包会把单行表达式的结果隐式 return 所以 return 也可以不用写

reversed = names.sort( { s1, s2 in s1 > s2 } )

Swift 提供了参数名的缩写,按顺序分配分别为 $0,$1,$2 以此类推

reversed = names.sort( { $0 > $1 } )

Swift 做了一些工作让代码可以使用 Operator Functions 让代码变的更简单

reversed = names.sort( { > } )

Trailing Closures | 尾随闭包

如果闭包作为参数传递给方法时,在最后一位,它允许被写在 ( ) 外面

reversed = names.sort() { $0 > $1 }

要是这方法只有这么一个闭包参数,那连括号都可以省掉了

reversed = names.sort { $0 > $1 }

其存在的意义是让代码更简洁,可读性更好


Capturing Values | 捕获数值

一个闭包可以获取在它周围上下文定义的常量或变量,哪怕这参数不存在了也依然可以

闭包属于引用类型,把闭包返回给一个对象时,如果闭包内有通过引用该对象,去方法其属性变量之类的操作,就会产生相互引用。从而导致的循环引用,会使内存无法释放


Nonescaping Closures | 非逃逸闭包

当一个闭包被当做参数传递给一个方法时,而且它会在这个方法返回后被调用,那它就算是个逃逸闭包

对于非逃逸的闭包,可以在闭包参数前声明关键字 @noescape 来告诉编译器,于是编译器就会做更多更激进的优化

func someFunctionWithNonescapingClosure(closure: @noescape () -> Void) {
    closure()
}

Autoclosures | 自动闭包

当我们把一个闭包作为参数传递的时候,这个闭包有一对醒目的花括号来表示它是个闭包。哪怕它只有一行表达式

// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serveCustomer(customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}
serveCustomer( { customersInLine.removeAtIndex(0) } )
// Prints "Now serving Alex!”

自动动闭包会把传递给函数的表达式包自动装成闭包,这样就不用每次都写一对 {} 了,只要在参数前声明 @autoclosure 关键字即可,但是这个闭包不接受任何参数,只计算闭包内的内容

// customersInLine is ["Ewa", "Barry", "Daniella"]
func serveCustomer(@autoclosure customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}
serveCustomer(customersInLine.removeAtIndex(0))
// Prints "Now serving Ewa!”

自动闭包隐式的就是个非逃逸闭包,如果要传递的是逃逸闭包,需要加上声明 @autoclosure(escaping) 即可


参考

  1. The Swift Programming Language (Swift 3.0) | Closures
  2. Autoclosures
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • 闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代...
    穷人家的孩纸阅读 1,660评论 1 5
  • 本章将会介绍 闭包表达式尾随闭包值捕获闭包是引用类型逃逸闭包自动闭包枚举语法使用Switch语句匹配枚举值关联值原...
    寒桥阅读 1,534评论 0 3
  • 闭包可以从定义它们的上下文中捕获和存储对任何常量和变量的引用。 这被称为关闭这些常量和变量。 Swift处理所有的...
    Joker_King阅读 566评论 0 2
  • “风吹这杨柳那唰啦啦啦啦啦……身穿大红袄,头戴一枝花,胭脂香粉她的脸上搽,左手一只鸡,右手一只鸭,身上还背着一个胖...
    斑锦阅读 231评论 1 9
  • 夏季的天犹如婴儿的脸,说哭就哭,说笑就笑! 中午晴得好好的,傍晚就乌云密布,天空突然降起了大雨!这雨下得很大很大,...
    神奇女侠ahua阅读 258评论 4 3