1、Closure

  • 闭包在 Swift 中非常有用。通俗的解释就是一个 Int 类型里存储着一个整数,一个 String 类型包含着一串字符,同样,闭包是一个包含着函数的类型。有了闭包,你就可以处理很多在一些古老的语言中不能处理的事情。这是因为闭包使用的多样性,比如你可以将闭包赋值给一个变量,你也可以将闭包作为一个函数的参数,你甚至可以将闭包作为一个函数的返回值。它的强大之处可见一斑。在 Swift 的很多文档教材中都说函数是“一等公民”,起初我还不是很理解“一等公民”是什么意思,但当我理解了闭包以及它的强大功能后,我恍然大悟、茅塞顿开、醍醐灌顶。原来闭包的这些特性就是“一等公民”的特性啊!

  • 闭包是功能性自包含模块,可以在代码中被传递和使用。一段程序代码通常由常量、变量和表达式组成,然后使用一对花括号“{}” 来表示闭合并包裹着这些代码,由这对花括号包裹着的代码块就是一个闭包。Swift 中的闭包与 C 和 Objective-C 中的 Block 以及其他一些编程语言中的 lambdas 比较相似。Block 和闭包的区别只是语法的不同而已,而且闭包的可读性比较强。

  • 闭包是引用类型,无论你将函数/闭包赋值给一个常量还是变量,实际上都是在将常量/变量设置为对应函数/闭包的引用,这也意味着如果你将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包。

  • 1)在 Swift 语言中有三种闭包形式:

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

        func myConpare(s1:String, s2:String) -> Bool {
    
            return s1 > s2
        }
    
        let namesArray:Array = ["Jill", "Tim", "Chris"]
    
        let names = namesArray.sort(myConpare)
  • 3)一般形式:

        { (parameters参数) -> returnType返回类型 in
    
            statements
        }
    • 可以使用常量、变量、inout、可变参数、元组类型作为闭包的参数,但不能在闭包参数中设置默认值,定义返回值和函数返回值的类型相同。

    • 闭包表达式中的 in 关键字表示闭包的参数和返回值类型定义已经完成,这些参数和返回值都将在下面的闭包函数体中得到处理。

          let namesArray:Array = ["Jill", "Tim", "Chris"]
      
          let names = namesArray.sort { (s1:String, s2:String) -> Bool in
      
              return s1 > s2
          }
  • 4)参数类型隐藏形式:

    • Swift 中有类型推断的特性,所以我们可以去掉参数类型。

          let namesArray:Array = ["Jill", "Tim", "Chris"]
      
          let names = namesArray.sort { (s1, s2) -> Bool in
      
              return s1 > s2
          }
  • 5)返回值类型隐藏形式:

    • Swift 中有类型推断的特性,所以我们可以去掉返回值类型。

          let namesArray:Array = ["Jill", "Tim", "Chris"]
      
          let names = namesArray.sort { (s1, s2) in
      
              return s1 > s2
          }
  • 6)return 隐藏形式:

    • 单行表达式的闭包可以通过隐藏关键字 return 来隐式地将单行表达式的结果作为返回值。

          let namesArray:Array = ["Jill", "Tim", "Chris"]
      
          let names = namesArray.sort { (s1, s2) in
      
              s1 > s2
          }
  • 7)参数名省略形式:

    • 闭包的使用非常的灵活,我们可以省略闭包参数列表中的参数的参数类型定义,被省略的参数类型会通过闭包函数的类型进行推断。同时,我们也可以在闭包函数体中通过使用闭包的参数名简写功能,直接使用 $0、$1、$2 等名字就可以引用的闭包参数值。如果同时省略了参数名和参数类型,那么 in 关键字也必须被省略,此时闭包表达式完全由闭包函数体构成。

          let namesArray:Array = ["Jill", "Tim", "Chris"]
      
          let names = namesArray.sort {
      
              $0 > $1
          }
  • 8)trailing 闭包形式:

    • 闭包可以做其他函数的参数,而且通常都是函数的最后一个参数。但是如果作为参数的这个闭包表达式非常长,那么很有可能会影响函数调用表达式的可读性,这个时候我们就应该使用 trailing 闭包。trailing 闭包和普通闭包的不同之处在于它是一个书写在函数参数括号之外(之后)的闭包表达式,函数会自动将其作为最后一个参数调用。

    • 当函数有且仅有一个参数,并该参数是闭包时,不但可以将闭包写在 () 外,还可以省略 ()。Swift 2.2 中可以不管参数的个数完全省略 ()。

          let namesArray:Array = ["Jill", "Tim", "Chris"]
      
          let names = namesArray.sort() {
      
              $0 > $1
          }
  • 9)闭包捕获:

    • 闭包可以在其定义的上下文中捕获常量或变量,即使定义这些常量或变量的原作用域已经不存在,仍然可以在闭包函数体内引用和修改这些常量或变量,这种机制被称为闭包捕获。在 Swift 中闭包的最简单形式是嵌套函数。嵌套函数就可以捕获其父函数的参数以及定义的常量和变量,全局函数可以捕获其上下文中的常量或变量。

          func increment(amount: Int) -> (() -> Int) {
      
              var total = 0
      
              func incrementAmount() -> Int {
      
              // total 是外部函数体内的变量,这里是可以捕获到的
                  total += amount
      
                  return total
              }
      
              // 返回的是一个嵌套函数(闭包)
              return incrementAmount
          }
      
          // 闭包是引用类型,所以 incrementByTen 声明为常量也可以修改 total
          let incrementByTen = increment(10)
          incrementByTen()    // return 10,incrementByTen 是一个闭包
      
          // 这里是没有改变对 increment 的引用,所以会保存之前的值
          incrementByTen()    // return 20
          incrementByTen()    // return 30
      
          let incrementByOne = increment(1)
          incrementByOne()    // return 1,incrementByOne 是一个闭包
          incrementByOne()    // return 2
          incrementByTen()    // return 40
          incrementByOne()    // return 3

iOS - Swift Closure 闭包的更多相关文章

  1. [ios][swift]使用swift闭包进行viewcontroller反向传值

    闭包参考:http://c.biancheng.net/cpp/html/2285.html   闭包详解 传值参考:http://www.tuicool.com/articles/vy2uUz Sw ...

  2. Swift: 比较Swift中闭包传值、OC中的Block传值

    一.介绍 开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值.在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包 ...

  3. iOS/Swift Tips 1

    1.重写hitTest方法,干预iOS事件传递过程 如下所示,view上有一个button,button一半的frame在父类view bounds之外, 按照iOS系统默认的处理逻辑, 如果点击按钮 ...

  4. Swift:闭包

    一.闭包的介绍 闭包表达式(Closure Expressions) 尾随闭包(Trailing Closures) 值捕获(Capturing Values) 闭包是引用类型(Closures Ar ...

  5. 4 .Swift函数|闭包

    在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...

  6. Swift使用闭包表达式

    Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是 ...

  7. Swift函数|闭包

    在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...

  8. Swift的闭包(一):闭包简介、闭包表达式的优化

    定义:Closures are self-contained blocks of functionality that can be passed around and used in your co ...

  9. Building gRPC Client iOS Swift Note Taking App

    gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...

随机推荐

  1. nginx完美支持yii2框架

    nginx完美支持yii2框架 server {listen 80;server_name www.peita.net peita.net;# default_server;access_log /d ...

  2. GCD 多线程 初探

    GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行,它类似NSOperationQueue但更复杂也更强大,并且可以嵌套使用.所以说,结合bloc ...

  3. 【转】MYSQL入门学习之七:MYSQL常用函数

    转载地址:http://www.2cto.com/database/201212/175864.html 一.数学函数  www.2cto.com           ABS(x)           ...

  4. html里文本保留换行格式

    用<pre></pre>把文本包起来

  5. Oracle绑定变量

    select * from table where id = ? 类似于上面这样的sql,如果不用绑定变量,每次执行时Oracle会认为是不同的sql,会在每次执行时生成一遍执行计划,而执行计划的生成 ...

  6. SDUT 2413:n a^o7 !

    n a^o7 ! Time Limit: 1000MS Memory limit: 65536K 题目描述 All brave and intelligent fighters, next you w ...

  7. Distinct<TSource>(IEqualityComparer<TSource> comparer) 根据列名来Distinct

    1. DistinctEqualityComparer.cs public class DistinctEqualityComparer<T, V> : IEqualityComparer ...

  8. noi 8465 马走日

    8465:马走日 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  1024kB 描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y ...

  9. CodeBlocks养眼的colour theme

    把如下的代码复制粘贴到这个文件:default.conf <?xml version="1.0" encoding="UTF-8" standalone= ...

  10. libevent安装及使用

    一.安装libevent 官网:http://libevent.org/ 选择最新版本下载,我选择的是libevent-2.0.22-stable.tar.gz,然后安装README文件中描述的方法编 ...