swift - 如何识别 Swift 中的强引用循环?

标签 swift reference garbage-collection swift2 strong-references

是否有工具或方法可以在我的 SWIFT 代码中定位强引用循环?

强引用循环是指类的两个实例在没有适当的安全性(weak/unowned)的情况下相互引用,因此阻止垃圾收集器一次性处理它们我创建的变量停止引用这些对象。

最佳答案

在 Swift 中查找强引用循环的方法与在 Objective-C 中相同。

您将从 Xcode 运行应用程序,充分运行应用程序以显示循环,然后点击“调试内存图”按钮 (debug memory graph)。然后你可以在左侧的面板中选择一个未释放的对象,它会显示内存图,通常可以清楚地说明强引用循环:

debug memory graph

有时内存周期并不那么明显,但您至少可以看到哪个对象保持对相关对象的强引用。如有必要,您可以向后追踪并确定是什么保持对此的强引用,等等。

有时仅仅知道是什么类型的对象保持了强引用是不够的,你真的想知道强引用是在代码中的什么地方建立的。 “malloc 堆栈”选项,如 https://stackoverflow.com/a/30993476/1271826 中所示, 可用于识别建立此强引用时调用堆栈是什么(通常让您识别建立这些强引用的精确代码行)。有关详细信息,请参阅 WWDC 2016 视频 Visual Debugging with Xcode .

您还可以使用 Instruments 来识别泄漏的对象。只需使用分配工具通过 Instruments 运行应用程序,重复(不仅仅是一次或两次)将应用程序返回到某个稳定状态,如果内存继续增加,那么你可能有一个强大的引用循环。您可以使用分配工具来识别哪些类型的对象没有被释放,使用“记录引用计数”功能来准确确定这些强引用是在哪里建立的,等等。

参见 WWDC 2013 视频 Fixing Memory Issues和 WWDC 2012 视频 iOS App Performance: Memory有关识别和解决内存问题的介绍。那里提出的基本技术今天仍然适用(尽管 Instruments 工具的 UI 发生了一些变化......如果您想了解稍微变化的 UI,请参见 WWDC 2014 视频 Improving Your App with Instruments)。

顺便说一句,“垃圾回收”指的是一个非常不同的内存系统,在这里不适用。

关于swift - 如何识别 Swift 中的强引用循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32262172/

相关文章:

html - iOS - UIWebView 加载 HTML 字符串包含 iframe 不起作用

java - 我怎样才能看到java正在使用哪个垃圾收集器

memory-leaks - 在 Lua 中丢失引用

C# 垃圾收集器、线程和编译器/抖动优化

swift - 如何在 MKMapView 中调整自定义注释图钉图像的大小?

ios - Core-Data 不保存在异步调用中

Swift Firestore 阻止检查字典键是否存在

c++ - 理解c++中的引用

c# - 是什么让表单成为根引用?

c++ - 如何使用数组按引用对对象进行排序? (以一种不那么愚蠢/复杂的方式。)