swift学习笔记 --- Closures

一.闭包创建语法

       {(parameters) -> return type in

         statements

  }

 例子 :

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

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

          return s1 > s2

    }

    var reversedNames = names.sort(backward)

    上面的是传入普通函数,我们也可以传入一个闭包

    reversedNames = names.sort({ (s1:String, s2: String) -> Boolin

    return s1 > s2

    })

二.闭包类型推断

     闭包被当做参数传入方法时,闭包的参数类型和返回值有可能被推断出来,这时我们可以省略参数类型和返回值,        因此上面的      例子也可以写成:

      reversedNames =names.sort({ s1, s2 inreturn s1 > s2 } )

      如果闭包里只有一条可执行语句,swift 是可以推断出返回值的,因此return 语句可以省略(前提是编译器知道必定有返回值)

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

二.简短的参数名

     如果我们知道函数的类型,既我们可以从函数里知道,传入函数的闭包需要几个参数每个参数的类型是什么,我们       可以省略闭      包的参数列表,in 关键词也可省略,因为此时闭包里全为可执行语句。通过$0,$1,$2......的方式来引用传      入的参数

    reversedNames =names.sorted(by: { $0 > $1 } )

三. Trailing Closures

    如果闭包是函数的最后一个参数我们可以把闭包写在函数调用的外边
    如: 
         reversedNames = names.sort() { $0 > $1 }
     如果函数只有闭包一个参数我们可以省略()

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


四.捕获值

     闭包可以捕获在闭包外面内容常量和变量,闭包可以引用和改变这些常量和变量。闭包的捕获使这些变量和常量不        被释放。

     func makeIncrementer(forIncrement amount: Int) -> () -> Int {

       var runningTotal = 0

       func incrementer() -> Int {

         runningTotal += amount

         return runningTotal

       }

      return incrementer

   }

   let incrementByTen = makeIncrementer(forIncrement: 10)

   incrementByTen()

   // returns a value of 10

   incrementByTen()

   // returns a value of 20

   incrementByTen()


五.闭包是引用类型

   当您将一个函数或一个闭包赋给一个常量或一个变量时,您实际上是在设置常量或变量来引用函数或闭包的函数。

六.闭包的Non-Escaping和 Escaping

   Non-Escaping Closures


      

     注意闭包没有从这函数体内逃逸。当函数结束,传入的闭包从函数体出来时,没有添加额外的引用。闭包的引用计数在函数开始执行和结束是相同的

   Escaping Closures

          
          逃逸闭包的引用计数在函数体内增加,导致函数开始执行和执行之后引用计数不想同。
          

   Escaping and Non-Escaping in Swift 3

          1.在 swift3闭包参数被默认为非逃逸,如果你想使闭包逃逸,你必须加上@escaping属性
          如果闭包是非逃逸的,编译器会做一些优化
          2.
            

    var completionHandlers: [() -> Void] = []

    func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {

    completionHandlers.append(completionHandler)

    }



    func someFunctionWithNonescapingClosure(closure: () -> Void) {

      closure()

    }


    class SomeClass {

       var x = 10

       func doSomething() {

        someFunctionWithEscapingClosure { self.x = 100 }

        someFunctionWithNonescapingClosure { x = 200 }

       }

   }


   let instance = SomeClass()

   instance.doSomething() 

   print(instance.x)

   // Prints "200"


  completionHandlers.first?()

  print(instance.x)

  // Prints "100"

  在逃逸闭包里必须用 self 来引用外围的内容,而非逃逸闭包则不用。



七.自动闭包

   一个自动闭包是一个没有参数,包裹一个表达式的闭包。当我们调用这个闭包它返回这个表达式的值。

     var customersInLine = [ "Chris" , "Alex" , "Ewa" , "Barry" , "Daniella" ]

  print(customersInLine.count)

  // Prints "5"


  let customerProvider = { "ddd";}

  print(customersInLine.count)

  // Prints "5"


  print("Now serving \(customerProvider())!")

  // Prints "Now serving Chris!"

  print(customersInLine.count)

  // Prints "4"


         

     


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值