美文网首页
swift3.0 - 闭包

swift3.0 - 闭包

作者: 07212a79db66 | 来源:发表于2016-08-11 16:16 被阅读370次

闭包的介绍

函数是闭包的一种
类似于OC语言的block
闭包表达式(匿名函数) -- 能够捕获上下文中的值

语法: in关键字的目的是便于区分返回值和执行语句
闭包表达式的类型和函数的类型一样, 是参数加上返回值, 也就是in之前的部分
{
(参数) -> 返回值类型 in
执行语句
}

闭包简写

  • 1.如果没有参数, 没有返回值, in和in之前的东西可以省略
  • 2.如果闭包是函数的最后一个参数, 可以写在()后面 -- 尾随闭包
  • 3.如果只有一个闭包参数, 那么()也可以省略 -- 尾随闭包

闭包使用:使用闭包代替block

  • 定义网络请求的类
class HttpRequestTool: NSObject {

    var callBack:(()->())?
    
    func loadData(callBack: () -> ()) {
        
        self.callBack = callBack
        DispatchQueue.global(attributes: DispatchQueue.GlobalAttributes(rawValue: UInt64(0))).async {
            print("网络请求数据:", Thread.current())
            DispatchQueue.main.async(execute: {
                callBack()
            })
        }
    }  
}

  • 进行网络请求,请求到数据后利用闭包进行回调
class ViewController: UIViewController {

    var httpTools : HttpRequestTool = HttpRequestTool()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
     
        httpTools.loadData { 
            print("加载数据完成,更新界面:", Thread.current())
        }
        
    } 
}

闭包的循环引用

  • 如果在HttpTool中有对闭包进行强引用,则会形成循环引用
  • 在Swift中检测一个对象是否销毁,可以实现对象的deinit函数

在xcode8可以利用内存图分析循环引用:
例如:这样写会造成循环引用


httpTools.loadData { 
            print("load data finish")
            self.view.backgroundColor = UIColor.red()
        }
        
        deinit {
        print("控制器销毁了")
    }
        

通过内存分析图查看表现为:

绿色的为出现循环引用.并且没用打印控制器销毁.改为如下代码:

weak var weakSelf = self
        httpTools.loadData { 
            print("load data finish")
            weakSelf?.view.backgroundColor = UIColor.red()
        }
        
        deinit {
        print("控制器销毁了")
    }

通过内存分析图查看表现为:

绿色消除,打印控制器销毁

// 析构函数(相当于OC中dealloc方法)
    deinit {
        print("ViewController----deinit")
    }
    

swift中解决循环引用的方式

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

 weak var weakSelf = self
        httpTools.loadData { 
            print("load data finish")
            weakSelf?.view.backgroundColor = UIColor.red()
        }
        
  • 方案二:和方案一类型,只是书写方式更加简单,可以写在闭包中,并且在闭包中用到的self都是弱引用

httpTools.loadData {[weak self] () -> () in
            print("load data finish")
            self?.view.backgroundColor = UIColor.red()
     }
     
  • 方案三:使用关键字unowned,从行为上来说 unowned 更像OC中的 unsafe_unretained,unowned 表示:即使它原来引用的对象被释放了,仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil
 httpTools.loadData {[unowned self] () -> () in
            print("load data finish")
            self.view.backgroundColor = UIColor.red()
        }

相关文章

  • swift中GCD的使用详情

    想看swift3.0使用GCD,请点击GCD详解 想看swift3.0闭包的使用和介绍,请点击Swift版闭包使用...

  • 逃逸闭包(escaping) vs 非逃逸闭包(nonescap

    升级到Swift3.0后,需要明确指出逃逸闭包,可以帮助编译器进行优化 逃逸闭包:可以逃离出所在函数执行的非逃逸闭...

  • Swift3.0朝圣之路-objc_setAssociatedO

    在Swift3.0中使用Runtime中的objc_setAssociatedObject绑定Block闭包,编译...

  • 9 闭包——《Swift3.0从入门到出家》

    9 闭包——《Swift3.0从入门到出家》 闭包 Swift语言中可以使用一块独立代码块替代函数的定义,称独立的...

  • Swift3.0 闭包

    闭包1.提前准备好的代码2.在需要的时候执行3.可以当做参数传递

  • swift3.0 - 闭包

    闭包的介绍 函数是闭包的一种类似于OC语言的block闭包表达式(匿名函数) -- 能够捕获上下文中的值 语法: ...

  • 闭包的逃逸

    在swift3.0以前,一个函数的参数的闭包的捕捉策略是escaping,如果是一个非逃逸闭包,需要显示的添加声明...

  • Swift3.0 闭包整理

    语法表达式 这里的参数(parameters),可以是in-out(输入输出参数),但不能设定默认值。如果是可变参...

  • Swift3.0 闭包整理

    bluajack的简书 语法表达式 这里的参数(parameters),可以是in-out(输入输出参数),但不能...

  • swift3.0闭包使用

    //参考http://www.jianshu.com/p/c0e43b13cc7a

网友评论

      本文标题:swift3.0 - 闭包

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