闭包的循环引用 与 解决(三种方法)

闭包的循环引用  与 解决(三种方法)

//******************************************************

//******************************************************

//******************************************************

闭包的循环引用

import UIKit


class ViewController: UIViewController {


    // 定义完成回调属性

    

    // 闭包的返回值可选

//    var finishedCallBack: ()->()?

    

    // 闭包属性可选

    var finishedCallBack: ((html: String)->())?

    

    override func viewDidLoad() {

        super.viewDidLoad()



        loadData { (html) -> () in

            print(html)

            print(self.view)

        }

    }

    

    

    deinit {

        print("控制器 88")

    }


    // 闭包应用场景:异步操作完成后,通过闭包的参数传递网络请求结果

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

        

        // 1. 记录完成回调

        finishedCallBack = finished

        

        dispatch_async(dispatch_get_global_queue(00)) { () -> Void in

            print("模拟异步加载数据")

            

            // 主线程回调

            dispatch_async(dispatch_get_main_queue(), { () -> Void in

                

                print("主线程回调")

                

                // 如果回调不能在当前方法立即执行,可以通过属性记录,在需要的时候用执行

//                finished(html: "<html>")

                self.finishedCallBack?(html: "hahah")

            })

        }

    }

}


213634_5y3c_2432308.png


//******************************************************

//******************************************************

//******************************************************

解决办法

import UIKit

class ViewController: UIViewController {


 

    // 定义完成回调属性

    

    // 闭包的返回值可选

//    var finishedCallBack: ()->()?

    

    // 闭包属性可选

    var finishedCallBack: ((html: String)->())?

    

    override func viewDidLoad() {

        super.viewDidLoad()


        // 方法三:Swift 的方法2

        // [unowned self] 表示闭包中的 self 都是 assign -> 如果 self 被释放,闭包中的 self 的地址不会修改

        // __unsafe_unretained类似,如果 self 被释放,同样会出现野指针

        loadData { [unowned self] (html) -> () in

            print(html)

            // self? 表示对象一旦被释放,不再访问其属性或者方法

            print(self.view)

        }

    }

    

    func demo2() {   //推荐使用

        // 方法二:Swift 的方法1

        // [weak self] 表示闭包中的 self 都是 弱引用

        //  __weak 类似,如果 self 被释放,什么也不做,更安全

        loadData { [weak self] (html) -> () in

            print(html)

            // self? 表示对象一旦被释放,不再访问其属性或者方法

            print(self?.view)

        }

    }

    

    // 方法一:OC 的传统方法

    func demo1() {

        // weak 属性在运行时可能会被改变 -> 执行对象一旦被释放,变成 nil

        // weak 属性不能是 let

        weak var weakSelf = self

        

        loadData { (html) -> () in

            print(html)

            // 闭包中,一定要使用 self.

            // weakSelf? 表示对象一旦被释放,不再访问其属性或者方法

            print(weakSelf?.view)

        }

    }

    

    deinit {

        print("控制器 88")

    }


    // 闭包应用场景:异步操作完成后,通过闭包的参数传递网络请求结果

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

        

        // 1. 记录完成回调

        finishedCallBack = finished

        

        dispatch_async(dispatch_get_global_queue(00)) { () -> Void in

            print("模拟异步加载数据")

            

            // 主线程回调

            dispatch_async(dispatch_get_main_queue(), { () -> Void in

                

                print("主线程回调")

                

                // 如果回调不能在当前方法立即执行,可以通过属性记录,在需要的时候用执行

//                finished(html: "<html>")

                self.finishedCallBack?(html: "hahah")

            })

        }

    }

}


闭包(Block) 的循环引用总结
  • Swift

    • [unowned self]

      • self不是可选项,如果self已经被释放,则出现野指针访问

    • [weak self]

      • self是可选项,如果self已经被释放,则为nil

    • [weak self]

    • [unowned self]

  • Objc

    • __unsafe_unretained typeof(self) weakSelf;

    • 如果self已经被释放,则出现野指针访问

    • __weak typeof(self) weakSelf;

    • 如果self已经被释放,则为nil



转载于:https://my.oschina.net/TaciturnKnightYQ/blog/539511

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值