簡體   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