zoukankan      html  css  js  c++  java
  • Swift学习笔记八:函数与闭包

    函数

    • 函数的定义: 函数名(形参列表) -> 返回类型
    // 有返回值 与 参数
    // 类型: (Int, Int) -> Int
    func sum(x: Int, y: Int) -> Int
    {
       return x + y
    }
     
    sum(x: 10, y: 11)
     
     
    // 无返回值
     
    // 类型: (Int, Int) -> ()
    funcsum4(x:Int, y:Int)
    {
       print(x + y)
    }
     
    sum4(x: 10, y: 11)
    • 函数的外部参数
      • 外部参数是在 形参 前加一个名字
      • 外部参数不会影响函数内部的细节
      • 外部参数会让外部调用方看起来更加的直观
      • 如果没有写外部参数, 函数在调用时, 默认会显示一个与形参变量同名的外部参数
      • 外部参数如果使用 _ , 在外部调用时, 会忽略形参的名字
      • 在 Swift 中, 使用 _ 就是可以忽略任意不感兴趣的内容
    // 类型: (Int, Int) -> Int
    funcsum(x:Int, y:Int) ->Int
    {
       return x + y
    }
     
    sum(x: 10, y: 11)
     
     
    // 类型: (Int, Int) -> Int
    func sum1(num1 x: Int, num2 y: Int) -> Int
    {
       return x + y
    }
     
    sum1(num1: 1, num2: 2)
    • 函数的默认值 
    // 通过给参数设定默认值, 在调用的时候可以任意纵使参数; 如果不指定的, 就使用默认值
    func sum3(x: Int = 1, y: Int = 2) -> Int
    {
       return x + y
    }
     
    sum3()
    sum3(x: 10)
    sum3(y: 1)
    sum3(x: 10, y: 20)
    • 输入输出函数
      • 当想要通过函数改变外部变量的值时, 在参数定义的类型的前面加 inout 关键字
      • 注意: 输入输出函数不能有默认值
    var x1 = 10
    var x2 = 99
     
     
    func demo(x: inout Int, y: inout Int)
    {
       let temp = x
        x = y
        y = temp
    }
     
    demo(x: &x1, y: &x2)
     
    print("*******(x1) ******(x2)")
     
     
    闭包
    • 在 OC 中 block 是匿名的函数
    • 在 Swift 中函数是特殊的闭包
    // 最简单的闭包
     
    //  () -> () 没有参数, 没有返回值的函数
     
    // 如果 没有参数, 没有返回值, 可以省略, 连 in 都一起省略
    let b1 = {
        print("hello")
    }
     
    b1()
     
     
    // 带参数的闭包
     
    // 闭包中, 参数, 返回值, 实现代码都是写在 {} 中
     
    //
    需要使用一个关键字 in, 来分隔 定义 与 实现
     
    // { 形参列表 -> 返回值类型 in 实现代码 }
    //  (Int) -> ()
    let b2 = {(x: Int) -> () in
        print(x)
    }
     
    b2(10)
     
     
    //  (Int) -> (Int)
    let b3 = {(x: Int) -> (Int) in
        
       print(x)
       
       
       return 10
     
    }
     
    b3(10)
    • 尾随闭包
      • 如果函数的最后一个参数是闭包, 函数参数可以提前结束, 最后一个参数使用 {} 包装闭包的代码, 函数的闭包参数的外部名称省略
      • 通过内联闭包表达示构成的闭包作为参数传递给函数或方法时, 总是能够推断出闭包的参数和返回值的类型, 因此, 闭包的参数和返回值的类型是可以省略的, 返回箭头 -> 和围绕在参数周围的括号也可以省略
    // @escaping: 逃逸闭包(函数返回之后再调用闭包)
    func text(completion: @escaping ([String]) -> ())
    {
       DispatchQueue.global().async {
           print("耗时操作(Thread.current)")
           
           // 模拟耗时操作
           Thread.sleep(forTimeInterval: 2)
           
           let array = ["1", "2", "3", "4"]
           
            // 主线程更新 UI
            DispatchQueue.main.async {
               print("主线程更新 UI (Thread.current)")
               
                completion(array)
            }
        }
    }
     
    // 函数调用的完整写法
    text(completion: { (result: [String]) -> () in
     
       print("请求到的网络数据*********(result)")
    })
     
    // 函数调用的简写, 省略: 函数的闭包参数的外部名称(completion)  闭包参数的类型([String])  箭头(->) 闭包参数的返回值类型()
    text() { result in
       print("请求到的网络数据*********(result)")
    }
     
    // 函数调用的简写
    text { (result) in
     
       print("请求到的网络数据*********(result)")
    }
    • 闭包的循环引用
    // 闭包中如果出现的 self, 要特别小心
     
    // 循环引用 单方向引用是不会产生循环引用的
     
    // 如果只是 闭包 对 self 进行了 copy, 闭包执行写成之后, 会自动销毁, 同时释放对 self 的引用
     
    // 同时需要 self 对闭包引用
    
    // 解决循环引用的方法
    
    // 方法1. OC 的方式
     
    // weak 只能修饰 var, 不能修饰 let, 因为 weak 修饰的变量可能在运行时被修改  ---> 指向的对象一旦被释放, 会被自动设置为 nil
    weak var weakSelf = self
     
    loadData
    {
        print(weakSelf?.view)
    }
     
     
    // 方法2. Swift 的推荐方法
     
    // [weak self] 表示 {} 中的所有 self 都是弱引用, 需要注意解包
     
    loadData { [weak self] in
     
       print(self?.view)
    }
     
     
    // 方法 3.
    // [unowned self] 表示 {} 中的所有 self 都是 assign 的, 不会强引用, 但是, 如果对象被释放, 指针地址不会变化, 如果对象被释放, 继续调用, 就会出现野指针的问题
     
    loadData { [unowned self] in
     
        print(self.view)
    }
  • 相关阅读:
    flex + bison multiple parsers
    Educational Codeforces Round 95 (Rated for Div. 2)
    python学习笔记 day20 序列化模块(二)
    python学习笔记 day20 常用模块(六)
    python 学习笔记 常用模块(五)
    python学习笔记 day19 常用模块(四)
    python学习笔记 day19 常用模块(三)
    python学习笔记 day19 常用模块(二)
    python学习笔记 day19 作业讲解-使用正则表达式实现计算器
    python学习笔记 day19 常用模块
  • 原文地址:https://www.cnblogs.com/fanxiaocong/p/6411622.html
Copyright © 2011-2022 走看看