Image Description

Swift中的闭包和Objective-C中的block很像,和其它编程语言中的匿名函数类似。

闭包是可以在代码中被传递和引用的功能性独立模块。它能够捕获和存储定义在上下文中的任何变量和常量的引用,并自动处理所有相关的内存管理操作,实际使用:

1.闭包当作参数传递

定义一个数组:

let names = ["XiaoLi", "XiaoWang", "XiaoMing", "XiaoJin", "XiaoHong"]

Swift标准库提供 sorted(by:)方法,会根据提供的排序闭包将已知类型额数组的值进行排序。

定义一个排序方法来当作闭包,当作 sorted(by:)方法的参数传入(这里一个有独立功能模块的函数,被当作一个参数传递,这就是闭包)。


import UIKit

func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}


var reversedNames = names.sorted(by: backward)


print(reversedNames)


//reversedNames 值为 ["XiaoWang", "XiaoMing", "XiaoLi", "XiaoJin", "XiaoHong"]

2.用闭包在两个页面之间传值

第一个页面有个输入文本框,输入的值作为闭包 closer的参数,被传递给第二个页面。


import UIKit

class FirstViewController: UIViewController {

    //输入文本框
    @IBOutlet weak var textField: UITextField!

    //为创建一个(String) -> () 的可选类型的闭包变量作为控制器的属性
    var closer: ((String) -> ())?

    //返回按钮的点击事件
    @IBAction func StartButtonDidClick(_ sender: AnyObject) {

        //首先判断closer闭包是否已经被赋值,如果已经有值,直接调用该闭包,并将输入的文字传进去。
        if closer != nil {
            closer!(textField.text!)
        }

        navigationController?.popViewController(animated: true)
    }
}

第二个页面,取第一个页面传递过来的闭包的值,显示在label上。


import UIKit

class SecondViewController: UIViewController {

    //显示文字的label
    @IBOutlet weak var label: UILabel!

    //重写这个方法
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        //拿到跳转的目标控制器
        let secondVC = segue.destination as! FirstViewController

        //为目标控制器的闭包属性赋值
        secondVC.closer = {

            //将闭包的参数(输入的文本内容)显示在label上
            self.label.text = $0
        }
    }
}

通过闭包传递了参数给标签。