添加addTextField输入框的UIAlertController销毁后未释放内存问题
问题原因
你代码中存在明确的循环引用链:
UIAlertController实例强持有所有添加到它内部的UIAlertAction对象- 你创建的
SUBMIT对应的UIAlertAction强持有自身的handler闭包 - handler闭包内部直接访问外部的
alertController变量,默认会对该实例产生强引用,最终形成alertController -> UIAlertAction -> handler -> alertController的永久强引用环,导致实例无法被释放。
你观察到的「不加addTextField就可以正常释放」属于UIKit内部的特殊优化逻辑,不代表此时没有循环引用,只是没有textField的简单弹窗场景下,UIKit内部主动打破了这层引用;当你添加了textField后,内部引用结构变化,优化逻辑不生效,本就存在的循环引用问题就暴露了。
解决方案
在handler的捕获列表中添加[weak alertController],打破强引用环即可,修改后的完整代码如下:
let alertController = UIAlertController(title: "Enter link", message: nil, preferredStyle: .alert) alertController.addTextField { (textField) in textField.placeholder = "www.xxx.com" } let cancel = UIAlertAction(title: "CANCEL", style: .cancel, handler: nil) let ok = UIAlertAction(title: "SUBMIT", style: .default) { [weak self, weak alertController] (_) in guard let self = self, let alertController = alertController else { return } guard let textFields = alertController.textFields, let textField = textFields.first else { return } if let text = textField.text { // 业务逻辑处理 } } alertController.addAction(cancel) alertController.addAction(ok) present(alertController, animated: true, completion: nil)
修改后弹窗dismiss时,整个实例就会被正常回收,不会再残留到内存中。
内容的提问来源于stack exchange,提问作者Nitanta Adhikari
相关产品推荐
相关产品推荐

