Home

dinghing

28 Aug 2016

Swift Closures

介绍

在Swift中闭包类似于Object-C和C中的block,作为一等函数可以被使用和嵌套在任何地方

闭包有三种形式:
全局函数是一个有名字但不会捕获任何值的闭包
嵌套函数是一个有名字并可以捕获到其封闭函数域内的值的闭包
闭包表达式是一个利用轻量级语法所写的,可以捕获其上下文中变量或常量值的匿名闭包

定义

闭包表达式语法有如下一般形式:
{ (params) -> returnType in statements }
闭包的函数体部分由关键字in引入,该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。关键字in之前是闭包表达式的参数和返回值,in之后是闭包表达式实际处理逻辑的代码区域。

闭包实现回调

闭包实现回调主要要实现以下三个步骤 :

  1. 定义闭包
  2. 闭包赋值(传送)
  3. 闭包调用

闭包实现回调用途

  1. 多线程编程
  2. 界面跳转时由于传值次数不是很多而不打算选择使用代理

对于多线程编程我们用一下代码来解释
在一个叫getValueViewController的类中有以下功能

var didEndLoad: ([[String: AnyObject]] -> Void)?//定义闭包函数
func initWithDate(){
     let q1: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
     dispatch_async(q1,{() -> Void in
        let url = NSURL(string: "http://www.example.com/patch/test.json")
        let request = NSURLRequest(URL: url!)
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config)
        let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
            do {
 
               // data = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                let object = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
                if let dictionary = object as? [String: AnyObject] {
                    dispatch_async(dispatch_get_main_queue()) {
                        self.dateFromJson = self.readJSONObject(dictionary)!
                        //print(self.dateFromJson)
                        self.didEndLoad?(self.dateFromJson)//使用闭包传值
                    }
                                       }
            } catch let error as NSError{
                print(error.localizedDescription)
            }
        });
        task.resume()
    })
}

对上面代码进行简单解释,我们使用多线程编程在一个服务器上获取一个json文件的值,然后将获取到的值在主线程中传递给一个闭包函数。 关于dispatch_queue_t 在此不做过多解释。

以上的闭包可以在其他任何类中被调用并获得相应的json传来的值。
比如在一个ViewController中需要获取刚才 的值我们可以用以下代码完成。

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    
    let tmp = getLecture()
    if( tmp.didEndLoad != nil){
           tmp.didEndLoad = {(obj) in
               self.getDate(obj)//obj中的值即为son文件的值,可以做任何处理
    }
}}

比写一个代理节约了不少时间和代码。而且Apple也是极力推荐多写闭包。

see tomorrow
dinghing at 16:27

scribble