繁体   English   中英

Swift - 遍历字符串中的字符会导致内存泄漏

[英]Swift - iterating through characters in string causes memory leak

这是我的第一篇文章! 我对 Swift 比较陌生,没有计算机科学背景,所以我仍然容易遇到很多新手问题 - 但到目前为止我已经能够解决所有问题,部分原因是浏览了优秀的答案在 StackOverflow 上。 然而,我遇到了一些真正让我难堪的事情,我花了整整一周的时间试图解决它,但没有运气。

我想要做的是从 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) }”。

顺便说一句,这种情况发生在相对较长的文本中 - 对于较短的文本,要么没有问题,要么 Instruments 无法检测到它。

但是,如果我通过根据空格将字符串分成单词来创建数组,就像我在英语等语言中想要的那样,没有泄漏 - 所以如果我在示例代码中将语言变量更改为“英语”,它可以正常工作(但当然没有给我我想要的数组)。 我认为问题可能出在“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 的所有内容,并且我尝试了各种弱/无主等内容,但似乎没有任何效果。 这是怎么回事,如何解决?

编辑:

所以看起来这可能只是模拟器和/或仪器的问题。 当我在设备上运行它,并只在 xcode 调试中监视内存使用情况时,即使执行 100 次以上也没有增加,所以我想这没问题……但它会在 Instruments 中显示泄漏似乎仍然很奇怪。

这是仪器错误(有很多问题)。 你的代码没问题。

我刚刚提交了一个错误报告 (FB7684067)。

以下简单的 macOS 命令行应用程序将在几分钟内增长到 1GB 以上:

import Foundation
let line = "124;5678;90123"
while true {
    let fields = line.components(separatedBy: ";")
    assert(fields[1] == "5678")
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM