快速内存管理:以正确的方式创建视图并避免内存泄漏

问题描述 投票:2回答:2

我对Swift内存管理有些困惑。我了解,如果removeFromSuperview为0,retainCount会释放该视图并使它符合垃圾回收的条件。但是,在跟踪CFGetRetainCount(myView)之后,我不确定retainCount的计算方式以及如何正确确保该视图在调用removeFromSuperview之后将完全释放。

这就是我为一个简单的UILabel得到的。代码:

let myLabel = UILabel()
   print("After creation")
   print(CFGetRetainCount(myLabel))
myLabel.frame = CGRect(x: 0, y: 0, width: view.frame.width - 40, height: 60)
   print("After frame set")
   print(CFGetRetainCount(myLabel))
myLabel.text = "Lorem ipsum"
myMainView.addSubview(myLabel)
   print("After added to superview")
   print(CFGetRetainCount(myLabel))

let otherLabel = UILabel()
otherLabel.frame = CGRect(x: 0, y: myLabel.frame.maxY + 20, width: view.frame.width - 100, height: 60)
   print("After referenced to position other view")
   print(CFGetRetainCount(myLabel))

myLabel.removeFromSuperview()
   print("After removed from superview")
   print(CFGetRetainCount(myLabel))

控制台:

After creation
3
After frame set
3
After added to superview
4
After referenced to position other view
4
After removed from superview
3

这使我提出了几个问题:

1)我知道CFGetRetainCount包含弱引用,但是在刚创建UILabel后3如何?

2)当我以后不需要它们时,我要在没有类范围引用的函数内添加视图(我也可以添加gestureRecognizers),并在删除包含视图之前使用以下方法删除它们:

myMainView.subviews.forEach({
   $0.removeFromSuperview()
})

这被认为是好的做法吗?手势识别器会阻止释放内存吗?

3)创建视图时,如何确保当计数已经为3时释放内存?

我想念什么?

ios swift xcode memory-management
2个回答
1
投票

DonMag上面共享的链接说明了为什么不应该使用keepCount的原因。ARC句柄为您保留计数。您需要担心的是保留周期。您上面提到的任何操作都不会创建保留周期,因此您应该相信编译器会从内存中删除该标签,只要该标签不再在任何地方被引用即可。发生保留周期的常见用例是引用自身和其他对象的委托和块。


0
投票

因此,对于那些到这里结束并想知道同一件事的人,CFGetRetainCount返回的结果不可靠,如here所指出。

为了确保在使用自定义类时释放了内存,您可以在类内部进行调用并进行测试

deinit {
  print("Memory deallocated")
}

如果未保留对象,则会自动调用上述方法。在此处查看文档:https://docs.swift.org/swift-book/LanguageGuide/Deinitialization.html

[其他泄漏可以使用仪器(在Xcode中:产品>配置文件>泄漏)或使用调试内存图工具进行测试

enter image description here

此处有更多说明:https://www.youtube.com/watch?v=1LnipXiSrSM

所以答案如下:

1 + 3)不要使用CFGetRetainCount。请参阅上面的说明。

2)这似乎工作正常,并且在我测试应用程序时释放了内存。

© www.soinside.com 2019 - 2024. All rights reserved.