14.6 Swift中weak解决循环强引用
/** (6)循环强引用 ARC不是万能的,它可以很好的解决内存过早释放的问题, 但是在某些场合下不能很好的解决内存泄漏的问题。 */
/** 循环强引用是造成内存泄漏的原因。接下来我们还是用代码来给大家讲解什么是循环强引用。 直接用官方例子 */
class Person { let name: String init(name: String) { self.name = name } var apartment: Apartment? deinit { print("(name) is being deininialized") } }
class Apartment { let number: Int init(number: Int) { self.number = number } var tenant: Person? deinit { print("Apartment #(number) is being deininialized") } }
/** 两个类各有一个属性,每个属性都是对方类的类型的属性,而这两个属性互相持有对方。 这就是所谓的循环强引用 */
// 这是强引用,不要认为可选类型就是弱引用啊,只有通过weak unowned才是弱引用 var john: Person? var number73: Apartment?
john = Person.init(name: "Johu Appleseed") number73 = Apartment.init(number: 73)
/** 上面的四句换对应 循环强引用讲解图1.png */
/** 这里面 apartment 和 tenant 两个对象是强引用, 也就是下面的john和number73设置为nil只是他们的强引用断开。 */ john!.apartment = number73 number73!.tenant = john
/** 我们可以看到在析构方法中没有打印,也就是这两个对象他们没有被销毁,造成了内存泄漏。但是我们没有办法在访问他们。 对应的 循环强引用讲解图2.png */ john = nil number73 = nil
/** 相互强引用或者说循环强引用会造成内存泄漏,为什么? 因为一块内存的释放的判断是没有对象占用它,相互强引用,那到底谁先释放呢?谁也不愿意先释放。 */
/** 在变量tenant前 加上 weak修饰, 也就是将其中的一个变量设置为弱引用就行了。 */
class Apartment1 { let number: Int init(number: Int) { self.number = number } weak var tenant: Person? deinit { print("Apartment #(number) is being deininialized") } }
print("--------------------->>")
var john1: Person? var number74: Apartment1? john1 = Person.init(name: "Johu Appleseed1") number74 = Apartment1.init(number: 74)
/** 上面的四句换对应 循环强引用讲解图3.png */ john1!.apartment = number73 number74!.tenant = john
/** 打印出来 --------------------->> Apartment #74 is being deininialized Johu Appleseed1 is being deininialized 循环强引用讲解图4.png
john1 对象的强引用没有了,设置为nil时被销毁,释放内存。同时number74所指向的内存也被释放了。 */ john1 = nil number74 = nil (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |