您的位置:

Swift闭包详解

一、Swift闭包类型

Swift中闭包(Closure)是一种自包含的代码块,它可以在代码中被传递和使用,类似于Objective-C中的Block和C中的函数指针。Swift提供了三种闭包类型

1、全局函数:有名字,但不能捕获任何值。


   func somefunction() {
          // some code
       }

2、嵌套函数:有名字,也能捕获封闭函数内的值。


 func closure(func: Int -> Int) -> Int {
         return func(1)
     }

   func increment(num: Int) -> Int {
         return num + 1
     }

   closure(increment)

3、闭包表达式: 没有名字,可以捕获上下文中的变量。


   let digit_names = [0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
                          5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"]

       let numbers = [16, 58, 510]

       let strings = numbers.map {
           (var number) -> String in
            var output = ""
           while number > 0 {
               output = digit_names[number % 10]! + output
               number /= 10
           }
           return output
       }
 

二、Swift闭包和OC Block区别

可以这么说,Swift闭包功能更加强大且语法更加简单,区别如下:

1、Swift的闭包可以根据上下文推断参数和返回类型,不需要声明。而Block需要进行显式声明。

2、Swift的闭包使用箭头”- >”来连接参数类型和返回类型,而Block使用”^”。

3、在Swift中,如果已知闭包参数的类型,则可以忽略参数类型,Swift编译器会自动推断。但是,Block必须显式地注明其参数类型和返回类型。

三、Swift闭包循环引用

闭包是引用类型,当闭包捕获外部变量,而该变量又是类实例的成员变量时就会出现循环引用。

如何解决循环引用问题:

1、捕获列表:


lazy var someClosure: (Void) -> String = {
         [unowned self] in
         return "闭包里的内容"
     }
 

2、弱引用:


 lazy var someClosure: (Void) -> String = { [weak self] in
         return "闭包里的内容"
     }
 

四、Swift闭包外部参数名

Swift闭包可以通过在参数列表之前放置具有描述性的字符串来使用外部参数名。

这在读取闭包时可以使代码更具可读性。

具体方法是把具有描述性的字符串写在闭包括号前面当做函数的形式参数。


func calculator(numbes: [Int], calculate: (Int) -> Int) -> [Int] {
         var result = [Int]()
         for num in numbes {
             result.append(calculate(num))
         }
         return result
     }

     print(calculator([1, 2, 3, 4, 5]) { "\($0)" })
 

五、swift闭包被关闭了会怎么样

如果开发人员忘记在闭包中捕获值就将它关闭使之变成不可变的,则会捕获大量数据,可能导致大量内存使用;如果开发人员忘记将闭包传递给适当的函数,则可能什么也没有停用。