在swift中抗楔,當我們使用split
方法的時候會返回一個Substring
數(shù)組:
public func split(maxSplits: Int = default, omittingEmptySubsequences: Bool = default, whereSeparator isSeparator: (Character) throws -> Bool) rethrows -> [Substring]
這跟java或者ObjectC不同洼畅,在其他語言中我們將會得到一個String
數(shù)組云石,為何swift返回一個新的類型Substring
呢谤逼?
解釋這個問題之前珊皿,先來看另外一個問題:
如何提升split
方法的效率擒权?
split
方法就是根據(jù)特定字符串將原數(shù)組切分成不同的部分,我們知道String
的存儲比較特殊适篙,一般都是在堆上,如果切分之后的子串也都存在堆上箫爷,無疑是一個巨大的開銷嚷节,況且方法調(diào)用者并不一定要用到每一個子串。
怎么辦呢虎锚?
那就共享內(nèi)存硫痰!
Substring
When you create a slice of a string, a Substring instance is the result. Operating on substrings is fast and efficient because a substring shares its storage with the original string. The Substring type presents the same interface as String, so you can avoid or defer any copying of the string’s contents.
split
方法返回的每一個字符串子串不額外開辟內(nèi)存空間,而是使用原數(shù)組的地址窜护,這樣就可以省下分配空間的開銷效斑。這是內(nèi)部實現(xiàn),無論是使用Substring
還是String
都可以做到柱徙,那么回到最初的問題缓屠,Substring
有啥優(yōu)勢?
答案就是护侮,這是一種優(yōu)秀的編程思想敌完!
考慮下面的case:
let bigContent : String = xxxx//獲取一大段文字
let partOfIt = splitContent(bigContent)//截取一小部分
summaryLabel.text = partOfIt//設(shè)置UILabel
根據(jù)上面的分析我們知道Substring
和原字符串是共享內(nèi)存的,因此當上述邏輯執(zhí)行完畢之后羊初,只要summaryLabel
沒有銷毀滨溉,bigContent
所指向的字符串就不會釋放,即使我們只使用了該字符串的一部分长赞。
為避免上述內(nèi)存泄漏情況的出現(xiàn)晦攒,我們應(yīng)當給summaryLabel
分配一個新的String
:
summaryLabel.text = String(partOfIt)
這樣bigContent
該釋放就釋放,和summaryLabel
不再相關(guān)得哆。
那為什么要用Substring
脯颜?因為如果split
返回的是[String]
,粗心的程序員很難會考慮到這么深入的問題柳恐,內(nèi)存泄漏很容易發(fā)生伐脖。因此在API設(shè)計的時候热幔,設(shè)置一個新的TypeSubstring
,如果寫的是summaryLabel.text = partOfIt
編譯器會報錯,提示類型轉(zhuǎn)化讼庇。
Important
Don’t store substrings longer than you need them to perform a specific operation. A substring holds a reference to the entire storage of the string it comes from, not just to the portion it presents, even when there is no other reference to the original string. Storing substrings may, therefore, prolong the lifetime of string data that is no longer otherwise accessible, which can appear to be memory leakage.