Swift语法--12-3闭包的循环引用

2016-03-12  本文已影响468人  20b347b28fc9

Swift语法--12-3闭包的循环引用


闭包循环引用产生条件

我们先看一段普通的代码

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        loadData { () -> () in
            print("被回调了")
            
            //在闭包中引用成员属性,需要加self
            //swift中能不写self就不写self
            //一般情况下只有区分参数,和在闭包中使用self
            self.view.backgroundColor = UIColor.greenColor()
        }
    }
    
    func loadData(finished: ()->())
    {
        callback = finished
        // 1.加载数据
        print("加载数据")
        
        // 2.执行回调
        finished()
        
        
    }

当我们想把里面的闭包作为一个属性储存起来

class ViewController: UIViewController {
    //设置属性用来保存闭包
    //成员属性要么初始化,要么设为可选类型
    //在设置闭包属性是可选类型时一定更要用一个()括住闭包的所有的类型, 否则只是指定了闭包的返回值是可选的
    // 错误写法: var callback: ()->()?
    var callback: (()->())?
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    
        loadData { () -> () in
            print("被回调了")
            self.view.backgroundColor = UIColor.greenColor()
            //闭包中强引用了self
        }
    }

    
    func loadData(finished: ()->())
    {
        callback = finished
        //viewController中的成员属性强引用了闭包
        
        // 1.加载数据
        print("加载数据")
        
        // 2.执行回调
        finished()
    }

    // deinit 相当于OC中的dealloc方法
    // 只要一个对象释放就会调用deinit方法
    deinit
    {
        print("88")
    }
}
闭包循环引用产生原因
闭包循环引用产生原因
解决方案
方案1:
// 解决方案一:   
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        weak var weakSelf = self  //可选类型
       loadData { () -> () in
            print("被回调了")
            //注意这里的改变
            //要对weakSelf进行解包
            weakSelf!.view.backgroundColor = UIColor.greenColor()           
        }
    }
方案2:
// 解决方案二:   
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    
        loadData {[weak self] () -> () in
            print("被回调了")
            //注意这里的改变
            self!.view.backgroundColor = UIColor.greenColor()           
        }
    }
方案3:
// 解决方案三:   
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    
        loadData {[unowned self] () -> () in
            print("被回调了")
            //注意这里的改变
            self.view.backgroundColor = UIColor.greenColor()           
        }
    }
总结

对应关系:

上一篇下一篇

猜你喜欢

热点阅读