swift-23闭包的循环引用

我以前做的swift笔记, 之前都是整理在onenote上, 最近想到整理出博客. 也方便自己查找, 可以当做自己的一份文档.


import UIKit

class ViewController: UIViewController {
    //属性 var 定义
    
    var completionCallBack: (()->())?

    override func viewDidLoad() {
        // 闭包如果出现 self. 要特别小心
        // "循环"引用 单方向对引用是不会产生循环引用!
        // 只是闭包对self进行了copy 闭包执行完成之后 会自动销毁 同时释放对self的引用
        // 同时需要 self 对闭包引用 才会形成循环引用
        // 'weak' must be a mutable variable, because it may change at runtime
        // weak 可能会被在运行时被修改 -> 指向的对象一旦被释放 会被自动设置为nil
        /**
         循环引用 需要打断链条
         法一 oc的方法
         */
        super.viewDidLoad()
//        weak var weakSelf = self
//        loadData {
//            /** 细节
//             ? 可选解包 如果 self已经被释放 不会向对象发送getter的消息 更加安全 
//             ! 强行解包 如果 self已经被释放 强行解包会导致奔溃
//            */
//            /**
//            weakSelf?.view 只是单纯的发送消息 没有计算
//             强行解包 因为需要计算 可选项不能直接参与到计算
//             */
//            //使用xcode8 的内存图 
//            print(weakSelf!.view)
//            print(self.view)
//        }
        
        /**
         法二 swift的推荐方法
         与oc的 __weak typeof (self) weakSelf = self; 等效
         [weak self] 表示 {} 中的所有self 都是弱引用 需要注意解包
         */
        loadData { [weak self] in
            print(self?.view ?? "self被释放")
        }
        
        /**
         法三 swift的另外一个用法 知道就好
         [unowned self] 表示 {} 中的所有 self都是assign的 不会强引用 但是 如果对象释放 指针地址不会变化
         与oc的 __unsafe_unretained typeof (self) weakSelf = self; 等效
         如果对象被释放 继续调用 就会出现野指针的问题
         self 不要解包
         */
        loadData { [unowned self] in
            print(self.view ?? "self被释放")
        }
        
    }

    func loadData(completion:@escaping ()->()) -> () {
        //使用属性记录闭包  self对闭包引用了
        completionCallBack = completion
        //异步
        DispatchQueue.global().async {
            print("耗时操作")
            DispatchQueue.main.async {
                //回调 执行闭包
                completion()
            }
        }
    }

    deinit {
        print("挥手拜拜")
    }
}
复制代码

转载于:https://juejin.im/post/5b963942f265da0ada5224f9

Swift 中,闭包是一种自包含的函数代码块,可以在代码中被传递和使用。闭包有能力捕获和存储其所在上下文中任意常量和变量的引用。当闭包引用了外部的对象时,为了避免循环引用(strong reference cycle),我们需要使用弱引用(weak reference)。 在闭包中使用弱引用可以防止闭包持有外部对象的强引用,从而避免循环引用的问题。循环引用指的是两个或多个对象之间相互持有对方的强引用,导致它们无法被释放,造成内存泄漏。 在 Swift 中,我们可以使用 `[weak self]` 或者 `[unowned self]` 语法来声明一个对外部对象的弱引用。`[weak self]` 会将对外部对象的引用标记为弱引用,而 `[unowned self]` 则标记为无主引用。 下面是一个使用弱引用闭包示例: ```swift class SomeClass { var completionHandler: (() -> Void)? func doSomething() { completionHandler = { [weak self] in // 使用 weak self 避免循环引用 guard let self = self else { return } // 在闭包中使用 self print("Doing something in \(self)") } completionHandler?() } } let instance = SomeClass() instance.doSomething() ``` 在上面的示例中,我们使用了 `[weak self]` 来声明对外部对象的弱引用。在闭包中,我们使用了 `guard let self = self else { return }` 来确保在闭包执行时,外部对象仍然存在。这样可以避免在闭包中使用已经被释放的对象。 需要注意的是,使用弱引用可能会导致外部对象在闭包执行期间被释放,因此在闭包中使用弱引用的对象时,需要进行额外的判断以确保其存在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值