Swift弱引用和无主引用

原创 Laughing  2017-07-09 17:49  阅读 73 次 评论 0 条

Swift也是采用ARC内存管理机制,所以如果两个引用类型相互之间进行引用,也会找到两个对象占用的内存都无法得到释放,最终造成内存泄漏。对于循环引用,swift提供了两种解决办法:弱引用无主引用

我们先通过下面的代码,演示一下swift内存管理的机制

  1. //: Playground - noun: a place where people can play  
  2.   
  3. import UIKit  
  4.   
  5. class ClassOne{  
  6.     deinit {//对象释放时,打印消息  
  7.         print("class one deinit")  
  8.     }  
  9. }  
  10.   
  11. class ClassTwo{  
  12.     var clsOne:ClassOne?  
  13.     init(cls:ClassOne?) {  
  14.         self.clsOne = cls  
  15.     }  
  16.     deinit {  
  17.         print("class two deinit")  
  18.     }  
  19. }  
  20.   
  21. var clsOne:ClassOne? = ClassOne()  
  22. var clsTwo:ClassTwo? = ClassTwo(cls: clsOne)  
  23. clsOne = nil//不会打印任何消息,因为clsTwo还有引用的clsOne  
  24. clsTwo = nil//打印ClassTwo释放,同时释放ClassOne。class two deinit class one deinit  

在此基础上,我们继续修改代码,让ClassOne也有一个属性引用ClassTWo

  1. //: Playground - noun: a place where people can play  
  2.   
  3. import UIKit  
  4.   
  5. class ClassOne{  
  6.     deinit {//对象释放时,打印消息  
  7.         print("class one deinit")  
  8.     }  
  9.     var clsTwo:ClassTwo?  
  10. }  
  11.   
  12. class ClassTwo{  
  13.     var clsOne:ClassOne?  
  14.     init(cls:ClassOne?) {  
  15.         self.clsOne = cls  
  16.     }  
  17.     deinit {  
  18.         print("class two deinit")  
  19.     }  
  20. }  
  21.   
  22. var clsOne:ClassOne? = ClassOne()  
  23. var clsTwo:ClassTwo? = ClassTwo(cls: clsOne)  
  24. clsOne?.clsTwo = clsTwo  
  25. clsOne = nil//不会打印任何消息,因为clsTwo还有引用的clsOne  
  26. clsTwo = nil//不会打印任何消息,因为ClsOne引用ClaaTwo  

这段代码,ClassOne跟ClassTwo相互引用,导致两个对象都无法释放内存空间

通过弱引用解决循环引用的问题

  1. //: Playground - noun: a place where people can play  
  2.   
  3. import UIKit  
  4.   
  5. class ClassOne{  
  6.     deinit {//对象释放时,打印消息  
  7.         print("class one deinit")  
  8.     }  
  9.    weak var clsTwo:ClassTwo?  
  10. }  
  11.   
  12. class ClassTwo{  
  13.     var clsOne:ClassOne?  
  14.     init(cls:ClassOne?) {  
  15.         self.clsOne = cls  
  16.     }  
  17.     deinit {  
  18.         print("class two deinit")  
  19.     }  
  20. }  
  21.   
  22. var clsOne:ClassOne? = ClassOne()  
  23. var clsTwo:ClassTwo? = ClassTwo(cls: clsOne)  
  24. clsOne?.clsTwo = clsTwo  
  25. clsOne = nil//不会打印任何消息,因为clsTwo还有引用的clsOne  
  26. clsTwo = nil//打印class two deinit class one deinit  

通过weak弱引用,ClassOne不会保持对ClassTwo的引用,所以当clsTwo释放后,clsOne的内存空间也就释放了

弱引用只能修饰Optional类型的属性。为了解决这个问题,swift提供了unowned无主引用来解决非Optional值类型属性的循环引用。

通过无主引用解决循环引用问题

  1. //: Playground - noun: a place where people can play  
  2.   
  3. import UIKit  
  4.   
  5. class ClassOne{  
  6.     deinit {//对象释放时,打印消息  
  7.         print("class one deinit")  
  8.     }  
  9.     init(clsTwo:ClassTwo) {  
  10.         self.clsTwo = clsTwo  
  11.     }  
  12.    unowned var clsTwo:ClassTwo  
  13. }  
  14.   
  15. class ClassTwo{  
  16.     var clsOne:ClassOne?  
  17.     deinit {  
  18.         print("class two deinit")  
  19.     }  
  20. }  
  21.   
  22. var clsTwo:ClassTwo? = ClassTwo()  
  23. var clsOne:ClassOne? = ClassOne(clsTwo: clsTwo!)  
  24. clsTwo?.clsOne = clsOne  
  25. clsOne = nil//不会打印任何消息,因为clsTwo还有引用的clsOne  
  26. clsTwo = nil//打印class two deinit class one deinit  
本文地址:https://www.lisen.me/454.html
版权声明:本文为原创文章,版权归 木子网 所有,欢迎分享本文,转载请保留出处!

发表评论


表情