13.闭包(特殊的函数)

  • 1.闭包的介绍

    • 闭包和OC中的block非常相似
      • OC中的block是匿名的函数
      • Swift中的闭包是一个特殊的函数
      • block和闭包都经常用于回调
    • 注意:闭包和block一样,第一次使用时可能不习惯它的语法,可以先按照使用简单的闭包,随着学习的深入,慢慢掌握其灵活的运用方法.
  • 2.闭包的使用

    • 1.先回顾一下block的使用

      @property(nonatomic,strong) void(^myblock)();
      // block 的格式: 返回值类型(^block名称) (参数列表)
      self.myblock = ^(){
      
              NSLog(@"block的打印");
      
       };
      self.myblock();
      
    • 2.闭包的基本介绍
      /*
      * 闭包和oc中的block非常相似
      * oc中的block类似于匿名函数
      * 闭包是用来定义函数
      * 作用: block 是用于保存一段代码,在需要的时候执行
      * 闭包也是用于保存一段代码,在需要的时候执行
      * 做一个耗时的操作
      */

      /*
       * 闭包的基本格式:
         in的含义是用来区分形参返回值和要执行的代码
       *  {
            (形参列表) -> (返回值)
             in
             需要执行的代码
          }
       *
       */
        loadData {
          
          print("回调")
      }
      
      func loadData(request:()->()){
      
          print("执行耗时操作")
          request()
      
      }
      
  • 3.闭包的几种格式

    • 1.将闭包通过实参传递给函数

      loadData (request: { 
         
          print("回调")
       })
       func loadData(request:()->()){
      
          print("执行耗时操作")
          request()
      
       }
      
  • 2.如果闭包是函数的最后一个参数,那么闭包可以写在函数()的后面
    loadData() {

          print("回调2")
         
     }
     func loadData(request:()->()){
    
         print("执行耗时操作")
         request()
    
     }
    
  • 3.如果函数只接受一个参数,并且这个参数是闭包,那么()可以省略
    loadData {

         print("回调2")
        
    }
    
    func loadData(request:()->()){
    
         print("执行耗时操作")
         request()
    
    }
    
  • 4.闭包的返回值和参数

/*
 *  两个闭包  创建一个 UIscrollview 上添加button
 *
 *
 */
let sc1 = createScrollview(buttonCount: { () -> Int in
    
    return 15
}) { (index) -> UIView in
    
    let width1 = 80
    let button = UIButton()
    button.backgroundColor = UIColor.red
    button.frame = CGRect(x:index*width1,y:10,width:width1,height:80)
    button.setTitle("标题\(index)", for: UIControlState(rawValue: 0))
    return button
    
    }
    
view.addSubview(sc1)
    
    /*
     * 要求定义一个方法来创建UIScrollView,
     * 1.并且上面有多个按钮,必须通过闭包来告诉该方法
     * 2.并且如何创建按钮也需要闭包来创建
     */
   
    // 5.将scrollview添加到控制器的view上
    // 特点: 没有写self
    // swift推荐:能不写self就不写self

    func createScrollview(buttonCount:()->Int,buttonIndex1: (_ num:Int)->UIView) -> UIScrollView {
    
    // 数组的数量
    let count = buttonCount()
    
    // 1.创建scrollview
    let sc = UIScrollView(frame: CGRect(x:0,y:64,width:414,height:100))
    sc.backgroundColor = UIColor.blue
    view.addSubview(sc)
    
    // 2.在scrollview上放置button
    
    for i in 0..<count {
        
        /*
        let button = UIButton()
        button.backgroundColor = UIColor.red
        button.frame = CGRect(x:i*width1,y:10,width:width1,height:80)
        button.setTitle("标题\(i)", for: UIControlState(rawValue: 0))
        sc.addSubview(button)
        */
        
        let button = buttonIndex1(i)
        sc.contentSize = CGSize(width:CGFloat(count) * button.bounds.width,height:100)
        sc.addSubview(button)
        
    }
    
    return sc
}
  • 5.循环引用

     import UIKit
    
    class ViewController: UIViewController {
    
     /*
      * 在swift中,如果在某个类中定义一个属性,那么这个属性必须要初始化,否则就会报错
      * 如果暂时不想初始化,那么可以在后面写上一个 ? 也就是可选类型
      */
    
      // 注意:这个是错误的写法,当前写法代表闭包的返回值可以是nil
      //var finsh: ()->()?
      // 下面是正确的写法
      var finsh: (()->())?
     
      override func viewDidLoad() {
      super.viewDidLoad()
     
      weak var weakSelf = self
      loadata { 
          
          print("回调")
          // 在swift开发中,能不写self就不写self,但是在闭包中必须写上self
          // 所以以后看到self基本上都是和闭包有关系
          weakSelf!.view.backgroundColor = UIColor.brown
            
          }
      
      }
    
      func loadata(finsh:()->())  {
      
      print("执行耗时操作")
      finsh()
      
      }
    
      override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
     }
    
    }
    

**循环引用解决:以上面的为例

方式一:
- 使用weak,对当前控制器使用弱引用
- 但是因为self可能有值也可能没有值,因此weakSelf是一个可选类型,在真正使用时可以对其强制解包(该处强制解包没有问题,因为控制器一定存在,否则无法调用所在函数)
weak var weakSelf = self
loadata {

       print("回调")
       // 在swift开发中,能不写self就不写self,但是在闭包中必须写上self
       // 所以以后看到self基本上都是和闭包有关系
        weakSelf!.view.backgroundColor = UIColor.brown

        }
      }

方式二:
- 和方案一类型,只是书写方式更加简单
- 可以写在闭包中,并且在闭包中用到的self都是弱引用
loadata { [weak self] () -> () in

            print("回调")
            // 在swift开发中,能不写self就不写self,但是在闭包中必须写上self
            // 所以以后看到self基本上都是和闭包有关系
            self!.view.backgroundColor = UIColor.brown

            }
        }

方式三:
 -  使用关键字unowned
 - 从行为上来说 unowned 更像OC中的 unsafe_unretained
 - unowned 表示:即使它原来引用的对象被释放了,仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil

        loadata { [unowned self] () -> () in

            print("回调")
            // 在swift开发中,能不写self就不写self,但是在闭包中必须写上self
            // 所以以后看到self基本上都是和闭包有关系
            self.view.backgroundColor = UIColor.brown

          }
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 介绍 Swift官方开发文档对于闭包的介绍是这样的:闭包是可以在代码中被传递和引用的功能性独立模块。Swift 中...
    Latte_Bear阅读 862评论 0 1
  • Swift 介绍 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 ...
    大L君阅读 3,175评论 3 25
  • 在上一篇文章Swift中的变量和常量中我总结了一些自己对于变量和常量的认识,最近学习了闭包,顺便给大家分享一下关于...
    老板娘来盘一血阅读 18,654评论 16 87
  • "闭包,Swift中的新概念,然而除了写法不同,实际上用法与用途都和OC中的Block没什么不同" 闭包 Swif...
    S_Lyu阅读 570评论 0 15
  • 使用playground来测试代码很有意思 Xcode 7.2 如果项目名称包含中文和数字 在数组中添加元素 会造...
    一黑阅读 562评论 0 0