Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Swift3.0基础之详细讲解Closure闭包结构的使用

$
0
0

源码Demo写的很详细,这里不再赘述,如下:

//创建一个全局的Closure,这是最后应该看的知识点
    //方式一:定义一个闭包变量其实就是定义一个特定函数类型的变量,方式如下。因为Closure变量没有赋初始值,所以我们把其声明为可选类型的变量。在使用时,用!强制打开即可。
    var globalCloure1:((Int, Int) -> Int)?
    
    //方式二:除了上面的方式外,我们还用另一种常用的声明闭包变量的方式。那就是使用关键字typealias定义一个特定函数类型,我们就可以拿着这个类型去声明一个Closure变量了,如下所示
    //定义闭包类型 (就是一个函数类型)
    typealias globalCloure2 = (Int, Int) -> Int
    var myCloure:globalCloure2?

    //全局方法中的Closure
    var globalCloure3:((Int, Int) -> Void)?
    var num11 = Int()
    var num22 = Int()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        //Swift3.0详细的闭包结构Closure的使用
        /**
         定义格式:
         Closure格式:let/var closure名称:((空/属性,空/属性) -> (空/属性))? 简式:let/var 名称:(() -> ())
         如果没有参数,没有返回值,可以直接写成:()/Void,如果有返回值,可以不加(),即:let/var 名称:(() -> Int),但是实现的时候最好和定义的格式一样,如closure3
         **/
        
        //111------创建一个无参数、无返回值的Closure
        let closure1:(() -> ())?
//        closure1 = { () -> () in
//            print("这是一个无参数、无返回值的closure")
//        }
        //为空的时候可不写:() -> () in 如下:
        closure1 = {
            print("这是一个无参数、无返回值的closure")
        }
        //调用
        closure1!()
        
        //222------创建一个有参数、无返回值的Closure
        let closure2:((Int,NSString) -> ())?
//        closure2 = { (a:Int,name:NSString) -> () in
//            print("姓名:\(name),  年龄:\(a)")
//        }
        //为空的时候可不写:-> () 可以忽略 如下:
        closure2 = { (a:Int,name:NSString) in
            print("姓名:\(name),  年龄:\(a)")
        }
        closure2!(20,"张三李四")
        
        //333------创建一个有参数、有返回值的Closure
        //如果有返回值,不加括号也可以,实现的时候建议和定义的形式一致
//        let closure3:((Int,Int) -> Int)?
//        closure3 = { (a:Int,b:Int) -> Int in
//            return a+b
//        }
//        let sum:Int = closure3!(10,5)
//        print("输出此时Closure3的求和结果:\(sum)")
        //上面两段代码都可以合成一段,1,2同理,但是执行closure的时候不需要再加!强制打开使用
        let closure3:((Int,Int) -> Int) = { (a:Int,b:Int) -> Int in
            return a+b
        }
        let sum:Int = closure3(10,5)
        print("输出此时Closure3的求和结果:\(sum)")
        
        //444------创建一个无参数、有返回值的Closure
        let closure4:(() -> Int) = { () -> Int in
            return 10
        }
        let val:Int = closure4()
        print("输出此时Closure4的返回值:\(val)")
        
        //555------创建和调用 一个全局的Closure
        //方式一:
        globalCloure1 = { (a:Int,b:Int) -> Int in
            return a+b
        }
        print("方式一。。。输出此时全局Closure的和:\(globalCloure1!(2,3))")
        //方式二:
        myCloure = { (a:Int,b:Int) -> Int in
            return a+b
        }
        print("方式二。。。输出此时全局Closure的和:\(myCloure!(2,3))")
        
        //666------创建和调用 带有Closure的方法
        //只有Closure结构一个参数的方法
        self.oneClosure { (a, b) in
            print("只有Closure结构一个参数的方法:后执行方法的调用111。。。a+b的和:\(a+b)")
        }
        //有参数,有一个Closure结构的方法
        self.oneClosure(num1: 2, num2: 3) { (a, b) in
            print("有参数,有一个Closure结构的方法:后执行方法的调用222。。。a+b的和:\(a+b)")
        }
        //有参数,有多个个Closure结构的方法
        self.oneClosure(num1: 2, num2: 3, aClosure: { (a, b) in
            print("有参数,有多个个Closure结构的方法:后执行方法的调用333。。。a+b的和:\(a+b)")
        }) { (c, d) in
            print("有参数,有多个个Closure结构的方法:后执行方法的调用333。。。a*b的积:\(c*d)")
        }
        
        //777------方法中有和全局一样的Closure,如globalCloure3,需要传递方法中的Closure,添加@escaping,即方法执行完以后执行Closure
        self.twoClosure(num1: 2, num2: 3) { (a, b) in
            print("通过全局的Closure传递值:后执行方法的调用777。。。a+b的和:\(a+b)")
        }
        //创建一个UIButton
        let myBtn = UIButton.init(frame: CGRect.init(x: 100, y: 100, width: 100, height: 100))
        myBtn.setTitle("Click me", for: .normal)
        myBtn.backgroundColor = UIColor.cyan
        myBtn.setTitleColor(UIColor.red, for: .normal)
        myBtn.addTarget(self, action: #selector(myBtnClick(btn:)), for: .touchUpInside)
        self.view.addSubview(myBtn)
        
        //888------使用@autoclosure描述的Closure
        self.autoclosure(a: 2, b: 3, num: (3>2))
        
    }
    //MARK:666------创建和调用 带有Closure的方法
    //只有Closure结构一个参数的方法
    func oneClosure(aClosure:((Int,Int) -> ())) {
        print("只有Closure结构一个参数的方法:先执行这个方法。。。。111")
        aClosure(2,3)
    }
    //有参数,有一个Closure结构的方法
    func oneClosure(num1:Int,num2:Int,aClosure:((Int,Int) -> ())) {
        print("有参数,有一个Closure结构的方法:先执行这个方法。。。。。222")
        aClosure(num1,num2)
    }
    //有参数,有多个个Closure结构的方法
    func oneClosure(num1:Int,num2:Int,aClosure:((Int,Int) -> ()),bClosure:((Int,Int) -> Void)) {
        print("有参数,有多个个Closure结构的方法:先执行这个方法。。。。。333")
        aClosure(num1,num2)
        bClosure(num1,num2)
    }
    
    //MARK:777-----方法中有和全局一样的Closure,如globalCloure3,需要传递方法中的Closure
    /**
     **注意:
     如果需要赋值给全局Closure时需要加@escaping修饰方法中的闭包参数,如果不加系统会提示你加上,因为这种情况默认你是在方法结束后执行的Closure
     解释如下:
     在以前版本闭包的使用时不用加@escaping的。当前版本,如果闭包没有回调Closure参数返回值,是不需要@escaping的。但是如果闭包传递了Closure参数,就会出现一种假设。那就是closure的内容会在函数执行返回后才完成。
     简单的说就是如果这个闭包是在这个函数结束前被调用,就是@noescape。
     闭包在函数执行完成后才调用,调用的地方超过了函数的范围,就是@escaping逃逸闭包。
     网络请求后结束的回调就是逃逸的。因为发起请求后过一段时间闭包执行。
     在swift3.0中所有闭包都是默认非逃逸的,无需@noescape。如果是逃逸的就@escaping表示。
     延迟操作,网络加载等都需要@escaping。
     **/
    func twoClosure(num1:Int,num2:Int,aClosure:@escaping ((Int,Int) -> ())) {
        print("有全局Closure结构的方法:先执行这个方法。。。。。777")
        num11 = num1
        num22 = num2
        globalCloure3 = aClosure
    }
    //按钮点击方法
    func myBtnClick(btn:UIButton) {
        if (globalCloure3 != nil) {
            globalCloure3!(num11,num22)
        }
    }
    
    //MARK:888------Closure中的@autoclosure其实就是省略了最外围的(),把后面的语句自动的封装成一个闭包:
    //只适用于无参数,有返回值的格式
    //num:(() -> Bool) -----> num: @autoclosure () -> Bool
    func autoclosure(a:Int,b:Int, num: @autoclosure () -> Bool){
        if num() {
            print("true")
        }else{
            print("false")
        }
    }
结果如图:



源码下载:https://github.com/hbblzjy/SwiftAllClosureDemo




作者:hbblzjy 发表于2017/7/21 10:59:10 原文链接
阅读:85 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>