swift 解决闭包强引用_swift 闭包循环引用 - CSDN
  • swift闭包强引用

    2016-01-08 17:31:41
    import UIKit class ViewController: UIViewController { // var finishedCallBack: (html: String) -> ()? var finishedCallBack: ((html: String) -> ())? override func viewDidLoad() {
    import UIKit
    
    class ViewController: UIViewController {
    
    //    var finishedCallBack: (html: String) -> ()?
        var finishedCallBack: ((html: String) -> ())?
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            //swift 写法3
            //unowned 和OC中的__unsafe_unretained一样 会造成野指针访问
            //iOS 4.0
            loadData {[unowned self] (html) -> () in
                print(self.view)
            }
        }
        
        func method2() {
            //swift 写法
            //使用weak修饰的变量 被系统回收时  会指向 nil
            //当对象指向nil 时  访问nil 不会造成野指针访问
            //和OC中的 __weak 一样 iOS 5.0
            loadData {[weak self] (html) -> () in
                print(self?.view)
            }
        }
        
        
        
        func method1() {
            //仿OC的解决办法
            //使用weak修饰的变量 被系统回收时  会指向 nil
            weak var weakSelf = self
            loadData { (html) -> () in
                print(weakSelf?.view)
            }
        }
        
        func loadData(finised: (html: String) -> () ) {
            
            //记录闭包
            finishedCallBack = finised
            dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    print("完成回调")
                    //在闭包中使用属性或者方法 必须加上self
                    //由于闭包可以从外界传递  如果不加self,调用上下文的就没有办法判断
                    self.finishedCallBack?(html: "hello world")
                })
            }
        }
    
        
        deinit {
            print("VC 88")
        }
    }
    

    展开全文
  •  15.9-解决闭包引起的循环强引用问题  */    var cr: CycleRef? = CycleRef.init()  // 引用计数为1     // 我们知道延迟存储属性,第一次访问的时候才初始化。  cr!.closure()

            /**

             15.9-解决闭包引起的循环强引用问题

             */

            

            var cr: CycleRef? = CycleRef.init()  // 引用计数为1

            

            // 我们知道延迟存储属性,第一次访问的时候才初始化。

            cr!.closure()  // 引用计数为 +1

            

            

            cr = nil   // 引用计数为-1

            

            /**

             我们可以看到如果不执行 cr!.closure()  的话,会打印出 deinit!

             那么执行了 cr!.closure(),产生了循环引用,没有打印出 deinit!

             

             两个对象:闭包对象,cr指向的对象。

             前提:闭包或者函数是引用数据类型。

             */





        class CycleRef {

            var a: Int = 9

            

            /**

             weak unowned不能修饰闭包,

             那么如何解决闭包强引用呢?

             系统有默认解决方法, 

             捕获列表

             

             // 一般使用这个,unowned修饰非可选类型,所以下面访问self不需要解包

             [unowned self] in

             

             

             

             // weak 修饰可选类型, 所以下面访问self! 要解包

             [weak self] in

             

             */

            lazy var closure: ()->Void = {

                

                /**

                 默认闭包会对它访问的对象执行强引用。

                 这个地方访问了self ,导致调用 该闭包的时候引用计数+1

                 如果闭包属性中没有直接或者间接访问self,就不会产生循环强引用。

                 */

                

                [unowned self] in

                print("a=\(self.a)")


                

    //            [weak self] in

    //            print("a=\(self!.a)")

                

                

                print("Closure!")

            }

            

            deinit {

                print("deinit!")

            }

        }





    展开全文
  • 模拟网络请求,封装工具类,使用闭包变量对闭包进行强引用 // // NetworkRequestTool.swift // Test // // Created by fe on 2017/2/28. // Copyright © 2017年 fe. All rights reserved. // import UIKit ...

    模拟网络请求,封装工具类,使用闭包变量对闭包进行强引用


    //
    //  NetworkRequestTool.swift
    //  Test
    //
    //  Created by fe on 2017/2/28.
    //  Copyright © 2017年 fe. All rights reserved.
    //
    
    import UIKit
    
    class NetworkRequestTool: NSObject {
    
        var callBack:((_ jisonData:String)->())? = nil //定义闭包变量
        
        //闭包类型:(参数列表)->(返回值类型)
    
        func loadData(callBack:@escaping (_ jisonData:String)->()) {
            
            //在这里对callBack闭包进行强引用,如果以后在控制器中在闭包内用到self则会造成循环引用
            self.callBack = callBack;
            
            DispatchQueue.global().async {//异步全局队列
                print("耗时操作\(Thread.current)")
                
                DispatchQueue.main.sync {//主队列回掉
                    
                    callBack("jisonData")
                    
                }
            }
        }
    }
    



    在控制器中调用工具类,在闭包内使用self会造成循环引用,使用三种方法可以解决闭包的循环引用



    //
    //  ViewController.swift
    //  Test
    //
    //  Created by fe on 2017/2/28.
    //  Copyright © 2017年 fe. All rights reserved.
    //
    
    import UIKit
    
    class ViewController: UIViewController {
    
        let requestTool = NetworkRequestTool()
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            
            
            
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            /*
            //第一种解决闭包循环引用的方法   weak var weakSelf = self
            //weakSelf?.view.backgroundColor = UIColor.red  (1)如果前面的可选类型,没有值,后面的代码不会执行 (2)如果前面的可选类型,有值,系统会自动将weakSelf进行解包,并使用weakSelf
            weak var weakSelf = self
            requestTool.loadData { (String) in
                print("----------\(String)")
                
                weakSelf?.view.backgroundColor = UIColor.red
            }
            */
            
            
            /*
            //第二种解决闭包循环引用的用法 [weak self]
            requestTool.loadData {[weak self] (String) in
                print("----------\(String)")
                
                self?.view.backgroundColor = UIColor.red
            }
            */
            
            
            //第三种解决闭包循环引用的用法 [unowned self]
            //__weak :OC的关键字,__weak修饰的弱引用,如果指向的对象销毁,那么指针会立马指向nil(0x0)
            //__unsafe_unretained :OC的关键字,__unsafe_unretained修饰的弱引用,如果指向的对象销毁,那么指针依然指向以前的内存地址,很容易产生“野指针”/“僵尸对象”
            //unowned :swift关键字,和OC的__unsafe_unretained关键字类似
            requestTool.loadData {[unowned self] (String) in
                print("----------\(String)")
                
                self.view.backgroundColor = UIColor.red
            }
     
        }
        
        deinit {
            print("-----------deinit")
        }
    
    }
    



    展开全文
  • 循环引用的产生原因:...对象对闭包强引用,即闭包是对象的属性。2.闭包中对对象强引用,闭包对闭包中的成员变量都会强引用一次。Student的实例对printNum闭包强引用,闭包中又对self进行了强引用。 class Student ...

    循环引用的产生原因:两个对象互相之间强引用,导致互相不能释放,后果就是两个对象都不释放,导致两个对象的内存都不能释放,这就会产生所谓的内存泄露。

    Swift闭包循环引用产生的两个条件

    1.对象对闭包强引用,即闭包是对象的属性。

    2.闭包中对对象强引用,闭包对闭包中的成员变量都会强引用一次。Student的实例对printNum闭包强引用,闭包中又对self进行了强引用。

       class Student {
            let num:Int
            
            init(studentNum:Int) {
                num = studentNum
                printNum = {
                    print(self.num)
                }
            }
            var printNum:(()->())
            
            deinit {
                print("deinit student")
            }
            
        }

    解决方案

    1.使用weak 或者 unowned 对self进行弱引用修饰,在闭包中使用弱引用后的self。区别在于前者得到的是可选,后者不是。

                printNum = {[weak self] in
                    print(self?.num)
                }
                printNum = {[unowned self] in
                    print(self.num)
                }

    2.在闭包中不对self进行引用,直接引用我们需要引用的值。

                printNum ={[num] in
                    print(num)
                }



    展开全文
  • import UIKit class ViewController: UIViewController {   ...闭包 ... // 闭包- strong -- VC ... //定义属性闭包 ... //swift 属性的默认 ...就是强引用  var finishedCallback: ((res: S

    import UIKit


    class ViewController: UIViewController {


        

        // VC --strong -- 闭包

        // 闭包- strong -- VC

        //定义属性闭包

        //swift 属性的默认 就是强引用

        var finishedCallback: ((res: String) -> ())?

        

        override func viewDidLoad() {

            super.viewDidLoad()

            

            loadData { [unowned self] (result) in

                print(result,self)

            }

        }

        

        // [unowned self] __unsafe__retained作用类似  -> 对象被回收是 内存地址不会自动指向nil 会造成野指针访问

        

        func methodInSwift2() {


            loadData { [unowned self] (result) in

                print(result,self)

            }

        }

        

        //[weak self] __weak typeof(self) 作用类似  -> 对象被回收是 内存地址会自动指向nil  更加安全 推荐使用这种方式

        func methodInSwift1() {

            loadData { [weak self] (result) in

                print(result,self)

            }

        }

        


        func methodInOC() {

            //1. 仿照OC 解决

            //弱引用的对象 又一次执行 nil的机会

            weak var weakSelf = self

            loadData { (result) in

                print(result,weakSelf)

            }

        }

        

        func loadData(finished: (result: String) -> () ) {

            

            finishedCallback = finished

            dispatch_async(dispatch_get_global_queue(0, 0)) { 

                NSThread.sleepForTimeInterval(3)

                

                //在主队列回调

                dispatch_async(dispatch_get_main_queue(), { 

                    //执行闭包

                    finished(result: "办证: 13581850000")

                    

                })

            }

        }


        //dealloc OC

        //析构函数

        deinit {

            print("886")

        }


    }

    展开全文
  • Swift闭包的使用

    2019-07-01 21:57:55
    本文主要介绍Swift闭包的使用:"闭包的定义"、"闭包的创建、赋值、调用"、"闭包常见的几种使用场景"和"使用闭包可能引起的循环强引用" 闭包的定义: 在Swift开发文档中是这样介绍闭包的:闭包是可以在你的代码中...
  • 循环强引用还会发生在当你将一个闭包赋值给类实例的某个属性,并且这个闭包体中又使用了这个类实例时。...解决闭包引起的循环强引用 在定义闭包时同时定义捕获列表作为闭包的一部分,通过这种方式可以解...
  • //写法一、 Swfit中的循环引用问题 (更安全) 可选项 loadData{ [weak self] ( ) ->( ) in ...//表示闭包中的self ,不做强引用,但是如果对象被释放,地址保留。 //如果self 真的被释放, 执行到此处
  • Swift 各种闭包各种使用 && 设置参数,函数传值
  • block
  • Swift闭包详解

    2016-04-13 15:41:28
    Swift函数章节中介绍的全局和嵌套函数实际上也是特殊的闭包闭包采取如下三种形式之一: 全局函数是一个有名字但不会捕获任何值的闭包 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 闭包表达式是
  • Swift 属性的默认是强引用 响应cell上的按钮事件 在cell中写一个闭包,VC的cell代理中调用 var switchCallBack:((_ sender:Bool)->(Void))?  方式一:[weak self] 【weak self】 和 __weak typeof(self) 作用...
  • 闭包循环引用问题: 1.问题代码 代码1:viewcontroll class ViewController: UIViewController { var client: HTTPClient? override func viewDidLoad() { super.viewDidLoad()
  • Swift的Trailing闭包, 捕获, 闭包引用类型
  • <iOS>Swift闭包

    2016-01-15 15:09:10
    Swift闭包 闭包是功能性自包含模块,可以在代码中被传递和使用。 Swift中的闭包与C和Objective-C中的blocks以及其他一些编程语言中的lambdas比较相似。 闭包可以捕获和存储其所在上下文中任意...
  •  15.8-闭包属性引起的循环强引用问题  所谓的循环强引用,是指两个对象相互强引用指向对方。谁都不撒手,造成这两个对象都不会被系统所释放,造成内存泄漏。    那么怎么解决它呢?将其中一个对象变成...
  • Swift 4.0学习之:闭包

    2018-03-14 09:56:51
    闭包 说到闭包,用法跟OC的block是一样一样的,基本格式是 { ()-&gt;() in } 通常是放到函数的实参里,举一个实际应用的例子: 目标:创建一个scrollorView,上面有10个按钮,要求有一定的可复用性,可...
  • 解析Swift闭包的循环引用
  • 概念:一个接受闭包作为参数的函数,该闭包可能在函数返回后才被调用,也就是说这个闭包逃离了函数的作用域,这种闭包称为逃逸闭包。当你声明一个接受闭包作为形式参数的函数时,你可以在形式参数前写@escaping来...
1 2 3 4 5 ... 20
收藏数 1,295
精华内容 518
关键字:

swift 解决闭包强引用