我要做的是从UITextView获取中文文本,然后将其转换为单个汉字数组,然后用于各种处理和分析。但是,这会导致泄漏。
在这个重现同样泄漏的大大简化的例子中,有一个TextView和一个Button;当用户按下按钮时,调用函数makeArray,它将文本转换为一个字符数组(实际上是单个字符的字符串,因为我需要它作为我将用它做的一些事情的字符串)。包含此函数的类TextProcessing被用作单例(是的,我知道显然单例应该是坏的,原因我不完全理解,但由于涉及代码其他部分的各种原因,它在那里工作得最好)是这个类的单个实例),并将UITextView中的文本传递给它,然后将其转换为数组,如下所示:
class ViewController: UIViewController {
@IBOutlet weak var textBox: UITextView!
@IBOutlet weak var doneButton: UIButton!
@IBAction func pressDoneButton(_ sender: Any) {
let textToAnalyze = textBox.text!
TextProcessing.textProcessing.makeArray(textToAnalyze)
}
}
class TextProcessing {
static let textProcessing = TextProcessing()
private let language = "Chinese"
private var sourceTextArray: [String]!
func makeArray (_ sourceText: String) {
if language == "Chinese" {
sourceTextArray = sourceText.characters.map { String($0) }
} else if language == "English" {
sourceTextArray = sourceText.components(separatedBy: " ")
}
// then do some stuff with this array
}
}
当我在Leaks Instruments上运行时,我得到“Malloc 16 Bytes”和“CFString”的泄漏,每个实例的数量与数组元素的数量大致相同(因此,串)。当我查看调用树并向下钻取时,问题行是“sourceTextArray = sourceText.characters.map {String($ 0)}”。
顺便说一句,这种情况发生在相对较长的文本中 - 短文本,或者没有问题或者仪器没有检测到它。
但是,如果我根据空格将字符串分成单词来构建数组,就像我想要的英语语言一样,那就没有泄漏 - 所以如果我在示例代码中将语言变量更改为“English”,它工作正常(但当然不给我我想要的数组)。我认为可能问题出在“map”方法中,因为它使用了一个闭包,并且很容易泄漏闭包,但是当我尝试其他方法将它放入一个字符数组时,例如使用for循环和以这种方式迭代每个字符,它仍然有同样的问题。
如果不是从UITextView获取文本,而是执行此操作:
class ViewController: UIViewController {
@IBOutlet weak var textBox: UITextView!
@IBOutlet weak var doneButton: UIButton!
@IBAction func pressDoneButton(_ sender: Any) {
let textToAnalyze = "blah blah put a long string of Chinese text here"
TextProcessing.textProcessing.makeArray(textToAnalyze)
}
}
没问题。同样,如果在makeArray函数中,如果我忽略sourceText而是执行此操作:
func makeArray (_ sourceText: String) {
if language == "Chinese" {
let anotherText = "blah blah some text here"
sourceTextArray = anotherText.characters.map { String($0) }
}
// then do some stuff with this array
}
也没有泄漏。因此,关于从文本框中获取字符串,将其传递给函数,然后将其放入字符数组中的组合导致泄漏。
我花了无数个小时在互联网上搜索关于Swift的ARC的一切,我尝试过各种各样的弱/无主等的东西,似乎没什么用。这里发生了什么以及如何解决这个问题?
修改
所以看起来这可能只是Simulator和/或Instruments的一个问题。当我在设备上运行它,并且只监视xcode调试中的内存使用情况时,即使进行100次以上也没有增加,所以我猜它没关系......但是它仍然显示它会在仪器中显示漏洞。
答案 0 :(得分:1)
这是仪器错误(存在很多问题)。你的代码没问题。
答案 1 :(得分:0)
我刚刚提交了一个错误报告(FB7684067)。
以下简单的macOS命令行应用程序将在几分钟内增长到超过1GB:
import Foundation
let line = "124;5678;90123"
while true {
let fields = line.components(separatedBy: ";")
assert(fields[1] == "5678")
}