了解闭包中的内存泄漏
啊,内存泄漏……起初,您甚至都不知道它们可以存在,然后您将其忽略,然后在不知道如何正确处理它们的情况下开始到处看到它们。
好的,所以现在也许是时候清楚地了解它们的时间,何时发生以及可以使用哪些工具摆脱它们了。
苹果公司发表了一篇很棒的文章,介绍了强有力的课堂参考周期。 很容易理解什么是内存泄漏以及在这种情况下如何避免内存泄漏。 但是,这是一种非常罕见的情况,并且很容易发现。 我发现有关闭包的部分更加令人困惑。 因此,让我们一劳永逸地阐明这一点。
带封闭的参考循环
首先,您必须了解闭包是什么以及闭包是做什么的。 我喜欢将其描述为一段代码,该代码在声明时会创建自己的临时类,该类包含对其执行自身所需的所有对象的引用。
让我们以一个简单的示例开始:一个具有CustomView的ViewController。 该CustomView有一个闭包,当点击按钮时会调用该闭包。
如您所见,我们有一个周期。 这意味着,如果退出此视图控制器,则无法将其从内存中删除,因为它仍被闭包引用。
这个例子很清楚,我们的viewController
有一个属性subview
,它有一个属性onTap
来捕获self
。 但是不幸的是,它可能变得更加复杂。
潜在周期的例子
您始终必须问自己的问题是: 谁拥有封闭件?
UITableView
如果您曾经构建过iOS应用程序,则必须在某个时候处理UITableView,而且很有可能,您还必须使用自定义按钮来处理自定义单元。
这是快速完成此操作的一种方法,首先,您有一个CustomCell,它具有一个动作闭合,可让您定义点击按钮时发生的情况。
GCD
您当然已经处理过Grand Central Dispatch,可以发现是否有周期吗?
在TableView示例中,如果您unowned
在onButtonTap
闭包中放weak
或unowned
,您将看到类似以下内容:
右侧的感叹号指示泄漏。 但是Xcode有时很难检测到泄漏。 您很可能有泄漏但没有感叹号。 在这种情况下,您只需要注意内存中的内容,如果看到不应该存在的内容,很可能会泄漏。