如何调查ios中的内存泄漏?

时间:2019-03-04 08:06:07

标签: ios swift memory-leaks instruments retain-cycle

我创建了一个简单的流程来测试ios应用程序中的内存。我在导航堆栈中有两个视图控制器。我在第一个视图控制器中显示警报,以允许用户移至下一个。以下是我正在使用的代码。

[\\s-\\.]?

在浏览资源中提到不应有一个强大的参考周期后,我在代码中使用了 unself self 。检查仪器中的泄漏,我得到了下图。

enter image description here

该图未显示绿色刻度线所示的泄漏。但是,当我在两个视图控制器之间来回移动时,内存使用情况图正在增加。是什么原因导致内存使用量增加(第一个问题)?

接下来,我还检查了用 self 取代 无名自我 的效果。我得到的结果与以前相同。这表明没有强有力的参考。参照此示例(第二个问题),我们如何确定强保留周期的存在?

enter image description here

2 个答案:

答案 0 :(得分:2)

从第二个问题开始。

撇开仪器,您的代码正在隔离UIViewController并就这样简单地将其关闭,让我们暂时不要考虑保留周期。

Strong vs Weak vs Unowned

1-通常,在创建属性时,除非引用被声明为弱属性或无主属性,否则引用是强引用。

2-标记为弱的属性不会增加引用计数

3-介于两者之间的无主引用,它们既不是强引用也不是类型可选 编译器将假定对象没有被释放,因为引用本身仍保持分配状态。

What是保留周期:

  

除非对父母或孩子有其他引用,否则他们都会成为孤儿。但是父母与孩子之间的保留周期阻止了   被释放,它们成为浪费的记忆。

     

孩子永远不要保留父母。如果有的话,用弱   在孩子中引用,以保持对父母的引用。

现在让我们看一下您拥有的东西,您正在使用UINavigationController & segue,根据apple

UINavigationController是LIFO堆栈。
  

导航控制器是一种容器视图控制器,它在导航界面中管理一个或多个子视图控制器。在这种类型的界面中,一次只能看到一个子视图控制器。

因此,检查您的UIViewController deinit函数,我认为告诉引用已释放没有问题。

现在,让我们尝试在UIAlertAction中查看[unowned self]中的其他内容。

When to use unowned self or weak self

  

您唯一真正想要使用[无主的自我]或[弱者]的时间   [self]是指您将创建一个强大的参考周期的时间。一个强壮的   参考周期是对象结束时存在所有权循环的情况   彼此拥有(可能通过第三方),因此他们   将永远不会被释放,因为它们都确保了每个   其他棍子。

     

在闭包的特定情况下,您只需要意识到   在其中引用的变量由闭包“拥有”。   只要关闭就可以保证这些对象是   周围。阻止该所有权的唯一方法是进行[无所有权   自我]或[弱自我]。因此,如果一个类拥有一个闭包,并且该闭包   捕捉到对该类的强烈引用,那么您拥有   闭包和类之间的参考循环。这还包括   如果该类拥有某个拥有闭包的东西。

正如您所说,同时切换[unowned self][self]并没有任何作用。

现在第一个问题,

仪器泄漏检查很简单,只需比较一段时间内内存的显着增加,然后根据发生的情况将它们相互比较,这不是100%的描述,而是接近的,因此只要弹出绿色勾号,表示您已通过测试。并不意味着您100%仍然安全,您可以在仪器底部直观地看到分配,观察值的变化(增加/减少) ..我认为您发现了问题。

调查您的案件,我认为您不会找到一个

答案 1 :(得分:1)

转到./main_test.go:6:9: undefined: Add 现在像截图一样在Edit Scheme -> Run -> Diagnostics上打勾。 Memory debug config之后,重新构建并运行。现在打开Malloc stack,您将在班级列表中看到发生内存泄漏的紫色图标。参见此屏幕快照Memory Debug Graph带有内存泄漏的示例存储库为Swift Memory Leak Demo,这是带有附加存储库Real Example picture with memory leak 的真实示例的内存泄漏视图 您可以对项目执行相同的步骤,以识别内存泄漏