美文网首页iOS开发
谈谈Swift中闭包

谈谈Swift中闭包

作者: kamto | 来源:发表于2017-08-02 14:09 被阅读16次

    Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 匿名函数比较相似。现在简单认识下Swift 中的闭包

    闭包的形式一般为:

    let Closure = {(parameters) -> returntype in
       statements
    }
    

    举个例子:

    let add = {(a: Int, b: Int) -> Int in 
       return a + b 
    }
    let result = add(1, 2)
    

    Swift中的闭包有很多可以优化

    比如根据上下文推断参数和返回值类型,我们可以优化成

    let add = {(a, b) -> Int in 
       return a + b 
    }
    let result = add(1, 2)
    

    比如从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)

    let add = {
        (a:Int,b:Int) in a+b
    }
    let result = add(1,2)
    

    也可以这样:

    let add:(Int,Int) ->Int = {
       (a,b) in a + b
    }
    let result = add(1,2)
    

    还可以使用简化参数名,如$0, $1(从0开始,表示第i个参数…)

    let add:(Int,Int) ->Int = {
       return $0+$1
    }
    let result = add(1,2)
    

    Swift的尾随闭包

    例子:

    func testFunction(testBlock: ()->Void){
     
        testBlock()
    }
    
    testFunction(testBlock: {
        print("尾随闭包")
    })
    

    也可简写成

    //推荐写法
    testFunction {
        print("尾随闭包")
    }
    

    相当于在Objective-C中

    - (void)testFunction:(void(^)())testBlock{
        testBlock();
    }
     [self testFunction:^{
         
     }];
    
    

    嵌套函数,也就是定义在其他函数的函数体内的函数。
    嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。

    例子:

    func makeIncrementor(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementor() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementor
    }
    

    一个函数makeIncrementor ,它有一个Int型的参数amout, 并且它有一个外部参数名字forIncremet,意味着你调用的时候,必须使用这个外部名字。返回值是一个()-> Int的函数。
    函数题内,声明了变量runningTotal 和一个函数incrementor。
    incrementor函数并没有获取任何参数,但是在函数体内访问了runningTotal和amount变量。这是因为其通过捕获在包含它的函数体内已经存在的runningTotal和amount变量而实现。
    由于没有修改amount变量,incrementor实际上捕获并存储了该变量的一个副本,而该副本随着incrementor一同被存储。

    let incrementByTen = makeIncrementor(forIncrement: 10)
    
    // 返回的值为10
    print(incrementByTen())
    

    类的属性也可以用闭包表示

    var name:String{
    
        get{
    
            return "Joe"
    
        }  
    
      set{
    
            println("name")
    
         }
    
    }
    

    下面看看闭包的使用,以cell为例

    typealias didSeletctBlock=(MyModel) -> Void
    //类似 oc 里的 typedef void (^didSeletctBlock)(MyModel *)
    
    class CustomCell: UITableViewCell {
    var didSeletctBlock :didSeletctBlock?
    
    //var testBlock:((_ model:MyModel) -> ())?
    
    
      @IBAction func onClickButton(_ sender: Any) {
            if didSeletctBlock != nil {
                didSeletctBlock!(myModel)
            }
    }
    
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell:CustomCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
                 cell.didSeletctBlock = {
                model in
                print(model.name)
            }
    //        cell.testBlock = {
    //            (model:MyModel) -> () in
    //            print(model.name)
    //        }
            return cell
        }
    

    我们初步了解了Swift里的闭包,其实在其他语言里也会用到闭包,比如在JavaScript中所有的function都是一个闭包。
    例子

    function a() { 
     var i = 0; 
     function b() {i++; } 
     return b;
    }
    var c = a();
    c();
    

    1、函数b嵌套在函数a内部;
    2、函数a返回函数b。
    3、当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

    相关文章

      网友评论

        本文标题:谈谈Swift中闭包

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