将文本分配给UILabel(iOS,Swift 4,Xcode 9)时内存泄漏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将文本分配给UILabel(iOS,Swift 4,Xcode 9)时内存泄漏相关的知识,希望对你有一定的参考价值。
我一直在研究一款没有故事板的新应用。一切顺利,直到我用仪器测试我的应用程序:每次我将一个字符串分配给标签时它就泄露了。当我使用故事板时,我没有那样的泄漏。
我已阅读以下资源以找到答案:
- UILabel memory leak?
- memory leak in cell with UILabel with ARC
- Instruments show "_NSContiguousstring" memory leak when scrolling UITableView
- Potential Leak, assigning NSString-Property to UILabel
- iOS: Debugging memory leaks for UILabel in swift
- UILabel and memory leak
- Generating UILabel inside a UIView / Memory leak
最流行的观点是,这是一个仪器错误,但它对我来说看起来是一个太明显的方法。
泄漏在空的应用程序中重现。在根视图控制器中:
class ViewController: UIViewController {
var label: UILabel?
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel()
view.addSubview(label!)
var textForLabel: String? = "Hello"
label?.text = textForLabel
//attempt to free the memory
textForLabel = nil
label = nil
//EDIT: added after @J.Doe and @Sh-Khan answers, but it's still leaking
label.removeFromSuperview()
}
}
在真实设备(iPhone SE 11.2)上的仪器中测试此应用程序时,我看到以下内容:
当我点击_NSContiguousString时,我发现内存泄漏出现在[UILabel setText:]中。
我试图将标签设置为弱,但是当我尝试将其添加为子视图时它变为零。
所以,我的问题是:
- 我现在和将来如何消除这种内存泄漏?
- 我应该仅在.xib / .storyboard文件中创建UI元素吗?
我是ios开发的新手,所以我觉得我错过了一些明显的东西。我将非常感谢任何帮助或建议。
编辑:根据@Sh-Khan和@J.Doe答案(非常感谢你们!),我添加了label.removeFromSuperview()
,但仍然有泄漏。
EDIT2:在@ J.Doe的帮助下,我了解到UILabel通过调用removeFromSuperview
从内存中释放并在之后将其设置为nil。仪器中的内存泄漏仍然存在,但我接受了他的回答,因为这是我想知道的。
PS:根据讨论,在阅读了关于NSString retain count之后,我认为内存泄漏的原因可能是因为我使用了无法发布的字符串文字。
也许我错了,但我想这个:
弱不会增加参考计数器。因此,将对象标签分配给弱var标签是没有意义的。这是因为弱var标签将为nil,因为您创建的对象没有任何引用(因此它将取消初始化)
让我们计算您的代码中有多少引用到您创建的对象Label。
label = UILabel() // 1
view.addSubview(label!) // 2
var textForLabel: String? = "Hello"
label?.text = textForLabel
//attempt to free the memory
textForLabel = nil
label = nil // 1
在视图中,您的对象标签还有1个引用。在执行label = nil之前,请调用label?.removeFromSuperview()。我想比你有0个引用 - >它会去掉。
编辑:
将UILabel的以下子类添加到您的代码中:
class MyLabel: UILabel {
deinit {
print("I am gone!")
}
}
将var label: UILabel?
改为var label: MyLabel?
和
label = UILabel()
到label = MyLabel()
并检查日志。你看到印刷品“我走了!”?
Edit2:打印出“我走了!”在一个空的项目中,仅作为代码:
import UIKit
class ViewController: UIViewController {
var label: MyLabel?
override func viewDidLoad() {
super.viewDidLoad()
label = MyLabel()
view.addSubview(label!)
let textForLabel: String? = "Hello"
label?.text = textForLabel
//EDIT: added after @J.Doe and @Sh-Khan answers, but it's still leaking
label?.removeFromSuperview()
label = nil
}
}
class MyLabel: UILabel {
deinit {
print("I am gone!")
}
}
第一次设定
textForLabel = nil
不会删除或使标签文本为零,因为标签已经复制了它
第二个设定
label = nil
你还不够
label.removeFromSuperview()
以上是关于将文本分配给UILabel(iOS,Swift 4,Xcode 9)时内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
在 UILabel 中显示 HTML 文本,性能问题。 [iPhone SDK、iOS 8、Swift]
设置为 nil 或 "" 时的 UILabel 文本属性使 UILabel 从视图中消失(Swift / Autolayout / iOS9.1)