美文网首页
循环引用

循环引用

作者: yellowzhou | 来源:发表于2020-09-08 17:42 被阅读0次

循环引用,即 A 强引用 B,B 强引用 A,对象销毁时会出现,A、B都无法销毁,因为A、B在相互等对方销毁,可是谁也没有办法先销毁

一、采用弱引用 避免循环引用

引用有3种情况:
1、默认强引用,即不做任何修饰
2、弱引用 [weak self],在对象被被释放后会将 self =nil,与 OC weak修饰一样效果
3、无宿主引用 [unowned self],对象释放后,不会设置为 nil,非安全调用会导致闪退,与 OC assign 修饰类似

class Util : NSObject {
    var block : (()->())?
    
    static let shared : Util = {
        let o = Util()
        return o
    }()
    
    func doSomething(callback: @escaping()->Void) {
        block = callback
        DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 5, execute: {
            print("callback ()->()")
            (self.block ?? {print("completion==nil")})()
        })
    }
}

class LoginViewController: UIViewController {
    var domain: LoginDomain!
    deinit {
        print("\(self) 释放")
    }
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        print(self.domain.title)
        // 弱引用,不会导致循环引用问题
        /*
         1、Util.shared 是单例,进程存在则不会被销毁
         2、doSomething 回调用 会被 Util.shared 单例【强引用持有】
         3、doSomething 回调中如果再强引用 self 时,就会导致相互 controller与Util.shared 相互持有对方,从而导致无法释放
         */
//        Util.shared.doSomething {
//            print("do()->Void " + self.domain.title)
//        }
        
        /*
         4、如果 doSomething 回调使用 弱引用,则 callback 不会强制持有 self(controller),及时 callback 被util.shared持有不释放,依然不会影响 controller 的 deinit
         5、弱引用可以使用 guard 简洁写法,然而 该写法可能会导致业务执行不完整的请求,guard let self = self else {return} 如果controller被释放了,callback 就直接 return了,后续业务无法执行
         */
        Util.shared.doSomething {[weak self] in
            // 通俗写法 guard let self = self else {return}
            guard let self = self else {
                print("self 已经释放")
                return
            }
            
            
            print("do()->Void guard " + self.domain.title)
        }
        /*
         6、不使用 guard,写法不那么优雅,需要 ?或 ??逐个判别对象
         */
//        Util.shared.doSomething { [weak self]in
//            if self == nil {
//                print("self 已经释放")
//            }
//            print("do()->Void " + (self?.domain.title ?? "") )
//        }
  }  
}

相关文章

  • 4-8 循环引用

    3种循环引用 自循环引用 相互循环引用 多循环引用 Block的循环引用 NSTimer 的循环引用 破除循环引用...

  • 循环引用的相关问题

    1、循环引用的种类(1)自循环引用(2)相互循环引用(3)多循环引用 如何破除循环引用?(1)避免产生循环引用(2...

  • iOS 内存管理面试题(循环引用)

    循环引用 循环引用的实质:多个对象相互之间有强引用,不能释放让系统回收。 如何解决循环引用? 1、避免产生循环引用...

  • 内存管理-循环引用

    三种类型循环引用 自循环引用 相互循环引用 多循环引用 自循环引用 假如有一个对象,内部强持有它的成员变量obj,...

  • iOS 循环引用

    1. 循环应用的分类: 自循环引用; 相互循环引用; 多循环引用; 自循环引用: 一个对象中有一个成员变量A; 如...

  • iOS开发 循环引用的几种场景

    delegate 循环引用如果delegate使用strong修饰容易引起循环引用 block 循环引用block...

  • Day2

    1 单方向的引用不会产生循环引用。循环引用:闭包引用了self,self引用了闭包。Swift推荐使用解决循环引用...

  • 避免Block的循环引用

    避免Block的循环引用 什么是循环引用,什么时候发生循环引用 1 循环引用就是当self 拥有一个block的...

  • iOS基础 Block解决循环引用

    block 循环引用循环引用 A对象持有B,B又持有A,互相强引用 解决循环引用问题:ARC 和MRC ARC:...

  • 2019-03-07 对WKWebView中的循环引用的理解

    WKWebView的这个循环引用很像定时器的循环引用。定时器的循环引用是因为系统runloop循环 强引用了执行...

网友评论

      本文标题:循环引用

      本文链接:https://www.haomeiwen.com/subject/zcdjektx.html