[英]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.