【问题标题】:Memory Leak closure in UIAlertControllerUIAlertController 中的内存泄漏关闭
【发布时间】:2018-12-13 12:14:43
【问题描述】:

我在设置UIAlertController 时出现内存泄漏,我看到其他线程在UIAlertController 中谈论内存泄漏。但我不知道如何更改我的代码,以便内存泄漏消失。我将itemSelected 从函数更改为计算属性,但它没有改变任何东西。

 protocol TriggerUIAlertController: class where Self: UIView {
        var itemsForPresenting: [String] { get }
        var titleForCancel: String { get }
        var titleForAlertController: String { get }
        var itemSelected: Int? {get set}
    }

    extension TriggerUIAlertController {

         func triggerUIAlerController() {
            let alertList = UIAlertController(title: titleForAlertController, message: nil, preferredStyle: .actionSheet)
            let closure = { (alert: UIAlertAction!) -> Void in
                let index = alertList.actions.index(of: alert)
                guard index != nil else {
                    return
                }

                ///produces memory leak, idk why though -> has to be checked
                self.itemSelected = index!
            }
            for x in itemsForPresenting {
                alertList.addAction(UIAlertAction(title: x, style: .default, handler: closure))
            }
            self.window?.rootViewController?.present(alertList,animated: true, completion: nil)
            let cancelAction = UIAlertAction(title: titleForCancel, style: .cancel, handler: nil)
            alertList.addAction(cancelAction)
        }
    }

顺便说一句:仪器在使用大约 5 分钟后使用总共 50gb ram 是否正常?

【问题讨论】:

  • 说到 Instruments 内存使用 - 5gb 是正常的,50 太多了。

标签: swift memory-leaks protocols uialertcontroller


【解决方案1】:

这不是由 UIAlertController 引起的泄漏,而是更普遍地由“保留周期”引起的泄漏,您可以在每个包含对 self 的引用的闭包或在闭包外创建的任何变量的情况下使用它。

你可以通过改变闭包的“定义”来避免它:

  let closure = { [weak self, weak alertList] (alert: UIAlertAction!) -> Void in
        guard let self = self, let alertList = alertList, let index = alertList.actions.index(of: alert) else { return }               
            self.itemSelected = index

您可以在此处找到更完整的解释: Swift closures causing strong retain cycle with self

代码审查:闭包的另一种实现可以是:

  let closure = { [weak self, weak alertList] alert in
        guard let self = self, let alertList = alertList, let index = alertList.actions.index(of: alert) else { 
            return
        }               
        self.itemSelected = index
  }

【讨论】:

  • 谢谢,我更改了代码,但它仍然显示内存泄漏.. 嗯
  • 我的错,alertList 和闭包之间也可能有一个保留周期。我更正了代码。
猜你喜欢
  • 2016-01-11
  • 1970-01-01
  • 2015-08-20
  • 2011-06-28
  • 2013-03-29
  • 2010-11-28
  • 2018-08-26
  • 2013-07-12
  • 2012-09-10
相关资源
最近更新 更多