美文网首页swiftswift 文章收集
swift基础语法(十三)——闭包

swift基础语法(十三)——闭包

作者: 芝麻绿豆 | 来源:发表于2016-02-09 19:03 被阅读41次

    介绍

    • 闭包和OC中的block非常相似

      • OC中的block是匿名的函数
      • Swift中的闭包是一个特殊的函数
      • block和闭包都经常用于回调
    • block写法总结:参考

        类型:
        返回值(^block的名称)(block的参数)
    
        值:
        ^(参数列表) {
            // 执行的代码
        };
    
    • 闭包的写法总结:
    闭包的写法:
        类型:(形参列表)->(返回值)
        技巧:初学者定义闭包类型,直接写()->().再填充参数和返回值
        值:
        {
            (形参) -> 返回值类型 in
            // 执行代码
        }
    

    基本使用

    • 定义网络请求类
    class HttpTool: NSObject {
        func loadRequest(callBack : ()->()){
            dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
                print("加载数据", [NSThread.currentThread()])
    
                 dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    callBack()
                 })
            }
        }
    }
    
    • 进行网络请求,请求到数据后利用闭包进行回调
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            // 网络请求
            httpTool.loadRequest ({ () -> () in
                print("回到主线程", NSThread.currentThread());
            })
        }
    

    闭包赋值的写法

            /*
            给闭包赋值:
            {
                (参数) -> (返回值) in
                // 代码块
            }
            */
            httpTool.requestData ({ () -> () in
                print("已经请求到网络数据");
                print("更新界面:\(NSThread.currentThread())")
            })
    
    • 如果闭包没有参数,没有返回值.in和in之前的内容可以省略
    httpTool.loadRequest({
            print("回到主线程", NSThread.currentThread());
        })
    
    • 尾随闭包写法:
      • 如果闭包是函数的最后一个参数,则可以将闭包的()写在{}前面
            httpTool.requestData () { () -> () in
                print("已经请求到网络数据");
                print("更新界面:\(NSThread.currentThread())")
            }
    
    • 如果函数只有一个参数,并且这个参数是闭包,那么()可以不写
    httpTool.requestData { () -> () in
                print("已经请求到网络数据");
                print("更新界面:\(NSThread.currentThread())")
            }
    

    循环引用

    • 如果在HttpTool中有对闭包进行强引用,则会形成循环引用
    class HttpTool: NSObject {
        // 定义属性,来强引用传入的闭包
        var callBack : (()->())?
        func loadRequest(callBack : ()->()){
            dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
                print("加载数据", [NSThread.currentThread()])
    
                 dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    callBack()
                 })
            }
            self.callBack = callBack
        }
    }
    
    • 解决方法
      • 方法一:
            weak var weakSelf : ViewController? = self
            httpTool.requestData {
               
                print("更新界面:\(NSThread.currentThread())")
                
                weakSelf!.view.backgroundColor = UIColor.orangeColor()
            }
    
    • 方法二:
            // 该方式不能省略赋值时的:() -> () in
            httpTool.requestData { [weak self] () -> () in
                print("更新界面:\(NSThread.currentThread())")
             
                self!.view.backgroundColor = UIColor.orangeColor()
            }
    
    • 方法三:该方法容易产生野指针,不建议使用
            // 该方式不能省略赋值时的:() -> () in
            httpTool.requestData { [unowned self] () -> () in
                print("更新界面:\(NSThread.currentThread())")
                
                self.view.backgroundColor = UIColor.orangeColor()
            }
    

    补充

    • Swift中没有dealloc方法
    • 析构函数:相当于OC中dealloc.也是对象销毁时会调用函数

    相关文章

      网友评论

        本文标题:swift基础语法(十三)——闭包

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