美文网首页iOS文章iOS开发资源
SwiftCafe 快报 - 了解闭包

SwiftCafe 快报 - 了解闭包

作者: SwiftCafe | 来源:发表于2015-10-12 07:20 被阅读271次
闭包

闭包(Closure) 是现代开发语言的必备特性,极大的提高了我们的开发效率。

关于闭包,你可以把它理解为一种特殊的变量或对象。简而言之,我们通常的对象,里面存储的是变量或对象的值,而闭包里面存储的是一段可执行的代码或函数,确切的说,是函数的地址。

我们都知道 UIButtonaddTarget 方法。

button.addTarget(self, action: Selector("handler:"), forControlEvents: UIControlEvents.TouchUpInside)

给这个按钮添加一个点击事件,我们传入一个 selector 作为事件名称,而这个 selector 的具体定义却在别的地方。所以这个不是闭包。

我们在来看一个 GCD 的例子:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
                // some code
            })

我们看到 GCD 调用,将要执行的代码块直接放到了调用处,而不是像上面那个 Selector 那样将定义和声明分开来。

这种方式的好处已经显而易见了,比如讲代码块和调用处放在一起,让代码的可读性更直观等等,再比如,使用闭包可以实现引用当前上下文中的变量,而传统的函数调用方式是不能实现的。

总而言之,闭包无比强大,更多原理还可以参看这篇文章:http://swiftcafe.io/2015/02/14/swift-tips-func-closure

这里主要给大家介绍下 Swift 语言中闭包的使用方式。

首先我们看到前面 GCD 例子中的最后一个参数:

{ () -> Void in
  // some code
}

这个就是闭包常量的表达方式,一对大括号是闭包的函数体,第一行中的 () -> Void 作为闭包函数的声明,小括号中是闭包的参数列表, -> 符号后面声明的是闭包的返回类型。

上面的那个闭包常量,我们还可以将它保存到变量中:

let callback: () ->Void = { () -> Void in
  // some code
}

很明显吧,变量的名字叫做 callback,它的类型是一个闭包 () -> Void ,后面将相同类型的闭包常量赋值给它。

同样的,闭包还可以接受参数,比如这样:

let sum: (left:Int, right:Int) -> Int = { (left:int, right:Int) -> Int in
  return left + right
}

闭包的调用也很简单,我们刚刚定义了一个 sum 闭包变量,我们就可以按照它的定义来调用它:

let result = sum(3,4)

闭包还可以作为类的属性:

class Calculator {
  var calculate:(number:Int) -> Int = { (number: Int) -> Int in
    return number * 2
  }
}

我们调用它的时候,就可以这样:

let calculator = Calculator()
let result = calculator.calculate(3)    //result = 6

细心的朋友就会想了,这不就是类方法么,我们完全可以这样定义:

class Calculator {

  func calculate(number: Int) -> Int {
    return number * 2
  }

}

就可以用同样的方式来调用这个函数,那定义一个闭包成员变量又好在哪儿呢?

刚才我们只说了其一,还没说其二,闭包变量的一个特点就是,我们可以以相同的调用接口,达成不同的底层实现,因为闭包是变量,所以闭包变量也可以声明称 Optional 类型的,那么我们继续看这个例子:

class Calculator {

  var calculate:((number:Int) -> Int)?

  func handleNumber(number:Int) -> Int {

    if  let closure  = self.calculate {
       return closure(number)
    }else {
       return number
    }

  }

}

这次,我们的闭包成员变量 calculate 仅仅作为一个 Optional 成员变量,我们预先没有给他定义任何实现。我们又定义了一个 handleNumber 方法,这个方法中对 calculate 进行了判断,如果我们给 calculate 提供了实现,就会按照 calculate 闭包的实现来处理传递进来的参数,否则就会直接将参数返回。

来看一下具体的调用方式吧:

let calculatorForDouble = Calculator()
calculatorForDouble.calculate = { (number:Int) -> Int in
  return number * 2
}
let result = calculatorForDouble.handleNumber(2)    //result = 4

let calculatorForDivisonBy2 = Calculator()
calculatorForDivisonBy2calculate = { (number:Int) -> Int in
  return number / 2
}
let resultDivision = calculatorForDouble.handleNumber(2)    //result = 1

这次明确啦,我们看到,我们用同样的 Calculator 类的两个实例,的同一个方法,实现了两个完全不同的操作,这也是闭包的一个精妙之处。

理解闭包其实不难,我们只需要把变量的概念扩散开,变量除了存放数字,字符串等这些值内容,还可以存放像闭包这样的执行内容,这也是我们编程思路的一个体现。

大家还可以看看这篇文章,对闭包概念有更深入的了解:http://swiftcafe.io/2015/02/14/swift-tips-func-closure

更多精彩内容可关注微信公众号:
swift-cafe

相关文章

  • SwiftCafe 快报 - 了解闭包

    闭包(Closure) 是现代开发语言的必备特性,极大的提高了我们的开发效率。 关于闭包,你可以把它理解为一种特殊...

  • SwiftCafe 快报 - Live Photos

    Live Photos 是 iOS 9 的一个新特性,它提供相对于传统照片更生动的展现方式。当用户按下拍照键的时候...

  • Block

    要了解Block需要先了解什么是“闭包性” 2.3 闭包性 上文说过,block实际是Objc对闭包的实现。 我们...

  • SwiftCafe 快报 - Array.contains

    而在 Swift 2.0 中,contains 被作为 Array 的一方法来使用了。所以我们只需这样调用即可: ...

  • SwiftCafe 快报 - 使用 SwiftyJSON 处理

    今天给大家介绍的 SwiftlyJSON 是一个用来处理 JSON 数据解析的第三方库。 说到 JSON 相信大家...

  • java,kotlin,dart闭包

    java闭包 kotlin闭包 dart闭包 了解不同语言之间的相同和不同。学习和进步。

  • 闭包的实际应用

    闭包 闭包闭包顾名思义封闭的包裹,那它到底是个啥包裹呢首先了解闭包前 我们先了解几个概念 作用域 作用域是程序运行...

  • 闭包、原型、原型链【前端面试问题(一)】

    一、闭包 什么是闭包?闭包你了解吗? 闭包就是能够读取其他函数内部变量的函数。 通俗一点呢? 通俗的讲就是函数a的...

  • Javascript 闭包

    如果要了解闭包,我们需要先了解闭包的由来,闭包的产生,源于JS的词法作用域 词法作用域 作用域是指一个 变量能够访...

  • SwiftCafe 快报 - defer 关键字

    defer 关键字也是 Swift 2.0 中提供的新语法,就像是上期中我们提到的 guard 关键字一样。都是 ...

网友评论

    本文标题:SwiftCafe 快报 - 了解闭包

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