closure(闭包)在iOS开发中的使用

来源:互联网 发布:js define是什么意思 编辑:程序博客网 时间:2024/05/16 01:48

闭包

1.闭包在swift中有点像C和C++的函数指针,跟OC中的block一致

闭包的定义

//定义

    //无参数无返回值的闭包

    var completionCallback :(()->())?

    //无参数有返回值的闭包

    var completionHandler:(()->Int)?

    //有参数无返回值的闭包

    var finishCallBack :((Int) ->())?

    //有参数有返回值的闭包

    var successHandler :((Int) ->(Int))?

//无参数无返回值的闭包

        completionCallback = { Voidin

            print("无参数无返回值的闭包执行了");

        };

        

        completionCallback!();

    

 //闭包赋值

        //无参数有返回值的闭包

        completionHandler = { Intin

            print("闭包被调用了");

            return20;

        };

        let a =completionHandler!();

        print(" a:\(a)")

        

        //有参数无返回值的闭包

        finishCallBack = { (a)in

            print("有参数无返回值的闭包 a:\(a)")

        };

        

        finishCallBack!(10);

        

         //有参数有返回值的闭包

        successHandler = {(a) ->(Int)in

            print("有参数有返回值 a:\(a)");

            return10;

        };

        

        let result =successHandler!(20);

        print(result);

 

// 闭包作为参数传递的情况

    func successFunction(success:@escaping (Int)->(Int)) -> () {

        

        successHandler = success;

        

        let result = success(10);

        

        print("successFunction result :::\(result)")

        

    }

    

    

    func doSomthing(finish:@escaping (Int)->()) -> () {

        

        finishCallBack = finish;

        

        finish(10);

        

        

    }

    

    func loadNetWorkData(completion:@escaping ()->Int) -> () {

        

        completionHandler = completion;

        

        let a = completion();

        

        print("a:\(a)");

        

        

    }

    

    func loadDatas(completion:@escaping ()->()) -> () {

        completionCallback = completion;

        DispatchQueue.global().async {

            print("耗时操作\(Thread.current)");

            //主线程更新UI

            DispatchQueue.main.async(execute: {

                print("\(Thread.current)");

                

                completion();

                

            })

        }

    }


  //闭包使用外部变量

    //定义一个闭包 左边参数名右边参数值记得加问号不然会报未初始化的错误

    var completionCallback :(()->())?

 //closure可以修改外部变量名了!!!!

        var a =10;

        

        completionCallback = { Void in

        

            print("使用外部参数===>\(a)");

                //使用外部参数===>10


            //如果是修改呢

            a = 20;

            print("修改后a的值\(a)");

          //修改后a的值 20

        };

        

        completionCallback!();

======>经过尝试在swift 3.0中可以改变外部变量的值了 这与OC中的不一样 OC如果需要修改外部参数需要加上__Block修饰


// 在swift中 经过侧是 在调用之前参数的值在外部可以修改了  我觉得应该是传递的是地址 所以可以修改了

//  在OC中  这样会输出 10

        var a =10;

        

        completionCallback = { Voidin

        

            print("使用外部参数===>\(a)");//使用外部参数===>10

        };

        

        a = 20;

        

        completionCallback!();


//闭包中的循环引用

// 测试方法 通过 出栈检测

 overridefunc viewDidLoad() {

        super.viewDidLoad()

        // 利用类似git的图标下面查看图层的东西可以检查是否有循环引用

        loadDatas

           

            print(self.view);

        }

    }

    func loadDatas(completion:@escaping ()->()) -> () {

        completionCallback = completion;

        DispatchQueue.global().async {

            print("耗时操作\(Thread.current)");

            //主线程更新UI

            DispatchQueue.main.async(execute: {

                print("\(Thread.current)");

                completion();

            })

        }

    }

    //析构函数

    deinit {

        print("我挂了");

    }


//  以上方法

NextViewController在出栈的时候并不会调用析构函数


//方法一  使用OC方法

weak var weakSelf =self;

        loadDatas

            print(weakSelf?.view);

        }

//方法二 苹果推荐方法

loadDatas { [weak self]in

           print(self?.view);

            

        }


以上两种方法都可以解决循环引用


// 另外Xcode8上 有点像git分支的那个图标可以帮我们使用图形化界面分析是否构成循环引用  具体步骤请看附件


本片纯是个人总结  改天我会总结一篇关于block的博客







































0 0
原创粉丝点击