2015-12-16 11:37:22 huangqingsong_5678 阅读数 172

解决方法:

1. 使用unowned 声明self(我自己测试不行,可能还需要设置其他的地方,有知道的可以评论留言,谢谢!),

代码:

<pre name="code" class="plain">{ [unowned self]() -> Void in
        self.doSomething()      
}



2. 使用weak 声明self(亲测可行)

代码:

{ [weak self]() -> Void in
        self?.doSomething()      
}






如果您有其他解决方案,请留言,谢谢!
2016-02-24 18:29:14 u014212588 阅读数 324


闭包循环引用问题:

1.问题代码

代码1:viewcontroll

class ViewController: UIViewController {

    
    var client: HTTPClient?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //weak var weakSelf = self
        
        let closure = {  (info info: String) -> () in
            
            print(info)
            print(self.view)
        }
        
        client = HTTPClient()
        
        client?.loadBigData(closure)
        
        
    }
    deinit{
        print("控制器 销毁")
    }
    

}

代码2: 网络工具类httpclient

class HTTPClient: NSObject {
    
    var callBack: ((info: String)->())?

    func loadBigData(finish: (info:String) -> ()){
        //获取闭包
        callBack = finish
        
        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
 
            NSThread.sleepForTimeInterval(2)
            
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                
                self.dealData()
                
            })
        }
    }
    //数据处理方法
    func dealData(){
        let str = "我是阳光的奇葩之都"
        callBack?(info: str)
    }
    
    deinit{
        print("网络请求类 销毁")
    }
}

细致观察:里面隐藏着一个循环引用链,导致controller 不能释放

关系是这样的   controller(强引用)->httpclient(强引用)->callback闭包(强引用)->self.view(即viewcontroller)  这样导致控制器不能释放

解决思路:将闭包callback对viewcontroller的强引用变成弱引用

修改后的代码

        weak var weakSelf = self
        
        let closure = {  (info info: String) -> () in
            
            print(info)
            print(weakSelf?.view)

        }





2016-07-16 20:25:40 Setoge 阅读数 304

循环引用的概念,不做赘述,下面直接用一个小 demo,说明 swift 闭包产生的循环引用:

class ViewController: UIViewController {

    // 声明一个闭包
    var closure:(() -> ())?


    override func viewDidLoad() {
        super.viewDidLoad()

        // 解决闭包循环引用

        // 方式01(iOS 5.0)
//        closure = {[weak self] () -> () in
//            
//            print(self?.view) // 要加 '?'
//            
//        }

        // 方式02(iOS 4.0)
//        closure = {[unowned self] () -> () in
//            
//            print(self.view) // 不加 '?'
//            
//        }

        // 方式03
        weak var weakSelf = self
        closure = { () -> () in

            print(weakSelf?.view)
        }
            }


// 重写 析构函数,看控制器是否被释放
    deinit{

        print("viewController挂了")
    }
}

验证控制器是否被释放,在 sb 中嵌套一层 跳转关系,运行跳转即可.
具体可到下面地址 下载 小demo.
https://github.com/moon13sun/-

2017-08-14 17:29:29 qq_30932479 阅读数 452

Swift 属性的默认是强引用

响应cell上的按钮事件

在cell中写一个闭包,VC的cell代理中调用

var switchCallBack:((_ sender:Bool)->(Void))? 


方式一:[weak self]      【weak self】 和 __weak typeof(self) 作用类似 -->对象被回收时,内存地址会自动置nil,更佳安全,推荐使用这种方式

 cell.switchCallBack = { [weak self] (isOn) in
                    self?.orderModel?.takeMySelf = isOn
                    self?.orderDetailModel?.takeMyself = isOn
                    self?.tableView.reloadData()
                }


方式二: 【unowned self】 和 __unsafe__retained作用类似—>对象被回收时,内存地址不会自定指向nil,会造成野指针访问


cell.switchCallBack = { [unowned self] (isOn) in
                    self?.orderModel?.takeMySelf = isOn
                    self?.orderDetailModel?.takeMyself = isOn
                    self?.tableView.reloadData()
                }

方式三:OC式的解决方式 

弱引用的对象,有一次执nil的机会  

weak var weakSelf = self

cell.switchCallBack = {  (isOn) in
                    weakSelf.orderModel?.takeMySelf = isOn
                    weakSelf.orderDetailModel?.takeMyself = isOn
                    weakSelf.tableView.reloadData()
                }



2016-12-23 16:19:48 sinat_20037505 阅读数 619

        /**

         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!")

        }

    }





Swift闭包循环引用

阅读数 311

没有更多推荐了,返回首页