String.count VS NSString.length

通常來講,Swift 裡的 String 是和 的NSString 橋接的,比如我曾寫過 NSString 和 String 究竟 有什麼區別 ?,總之這裡我們主要來討論一下,String計數的NSString長度 到底有什麼區別。

String.count

String.計數 實際上是 String.人物.計數 (Swift 早期版本),Swift 裡的 String ,早期 計數 屬性就是單純的字符數量,這和 的NSString 是一樣的,但很快就加入了擴展字形集群特性,比如一個 Emoji 表情,它的編碼長度是普通字符的兩倍,但這是視覺上的【一個】字符,於是它在 String 裡算【一個】字符。

比如:

需要注意的是斯威夫特的使用延長字形集群 Character 值意味著字符串連接和修改可能不總是影響一個字符串的字符計數.

注意 Swift 為 字符 值使用的擴展字形集群意味著字符串的創建和修改可能不會總是影響字符串的字符統計數。

NSString.length

對於很有歷史感的 的NSString 來說,就沒那麼複雜了,它就是字符的數組,所以它只會單純計算字符數量,由於一個 Emoji 就是用兩個字符的長度表達的,所以在這裡,長度為 2 :

兼容性

如果不注意這個問題,就會遇到很多奇怪的小錯誤,比如在設定富文本顏色的時候,會導致文本末尾異常,會導致 Emoji 亂碼等等。因為富文本是 NSAttributedString ,它的長度計算是基於 UTF16 字符長度的,而不是合併後的【視覺】字符長度:

注意高亮行,這裡 NSRange(位置: 0, 長度: 小號.計數) 使用了 String計數 屬性,讀出的長度應該是 1 ,但 NSMutableAttributedString 是以 UTF16 字符長度做計算,所以字符串長度應該是 2 ,結果導致為半個 Emoji 字符添加顏色,輸出內容為亂碼。

將字符串轉換為 的NSString 後獲取 長度 則得到了正確結果。

Swift 裡的 UTF16 字符串長度

那麼,每次使用,都要明顯地寫成 ("" 的NSString).長度 的形式嗎?雖然寫個 延期 也不是不行,不過,我們其實也可以直接從 String 原生地獲取這個長度:

討論

String的NSString 有很多名稱類似但功能相同的方法,但得到的結果卻可能並不完全一致,要小心 Swift 對字符串的處理,這些問題往往會在一些細節的地方體現出來,比如輸入法移動光標的 API,其中移動 1 長度,是 1 UTF16 字符長度,比如 Emoji,計數是 2 而不是 1,如果不注意這個細節,就會導致一些自動化功能在遇到 Emoji 表情或者某些生僻中文字符時計算出錯,因為這些符號視覺上是一個字,但實際上使用了可變長的多個 UTF16 字符長度。

 

延伸閱讀

HTTPS://stackoverflow.com/a/36268059

HTTPS://stackoverflow.com/a/29833042

HTTPS://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html

HTTPS://www.cnswift.org/strings-and-characters

本文由 落格博客 原創撰寫:落格博客 » String.count VS NSString.length

轉載請保留出處和原文鏈接:https://www.logcg.com/archives/3253.html

由...出版 落格博客

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

發表評論

您的電子郵件地址不會被公開. 必填字段標 *