關(guān)于編碼知識:Unicode字符集、UTF8、UTF16、UTF32編碼、大小端等知識點,更多可以看我的字符集編碼演變史,是入門科普文,自認(rèn)為還不錯。
為何探究NSString?我司代碼中使用c++自定義了CEQString8 CEQString16等類型,可以和NSString互轉(zhuǎn),可能對c++有抵觸吧,所以就沒細(xì)看實現(xiàn)。但今日遇到某個問題需要了解下實現(xiàn),在c++代碼實現(xiàn)中發(fā)現(xiàn)其實也不過是編碼轉(zhuǎn)換,自定義類用一個char數(shù)組存儲了unicode碼通過utf8編碼后的數(shù)據(jù)。
接著我寫了個Demo簡單探究了下NSString的數(shù)據(jù)結(jié)構(gòu):
// ======================================================================================================
// Demo 涉及到的四個 Unicode 字符
// \u{4e00} 對應(yīng)中文“一” utf8 {e4 b8 80} utf16 {4e00}
// \u{4f60} 對應(yīng)中文“你” utf8 {e4 bD a0} utf16 {4f60}
// \u{0061} 對應(yīng)字母“a” utf8 {61} utf16 {0061}
// \u{0032} 對應(yīng)數(shù)字“2” utf8 {32} utf16 {0032}
// ======================================================================================================
// Unicode 段劃分 UTF8 編碼 有效編碼位
// 0x0 ~ 0x7F 0XXXXXXX 7
// 0x80 ~ 0x7FF 110XXXXX 10XXXXXX 11
// 0x800 ~ 0xFFFF 1110XXXX 10XXXXXX 10XXXXXX 16
// 0x10000 ~ 0x10FFFF 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX 21
// =======================================================================================================
// Unicode 段劃分 UTF16 編碼 有效編碼位 備注
// 0x0 ~ 0xFFFF XXXXXXXX XXXXXXXX 2 字節(jié) Unicode中去除了0xD800~0xDFFF區(qū)間
// 0x100000 ~ 0x10FFFF (0xD800 ~ 0xDBFF) (0xDC00 ~ 0xDFFF) 4 字節(jié) 前者高代理區(qū) 后者低代理區(qū)
// =======================================================================================================
// Unicode 段劃分 UTF32 編碼 有效編碼位 備注
// 0x0 ~ 0x10FFFF XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX 4 字節(jié)
// =======================================================================================================
NSString *string = [NSString stringWithFormat:@"一a你2"];
NSUInteger length = string.length; // 4個
const char *pCh_UTF8 = [string cStringUsingEncoding:NSUTF8StringEncoding];
const char *pCh_UTF16 = [string cStringUsingEncoding:NSUTF16StringEncoding];
const char *pCh_UTF32 = [string cStringUsingEncoding:NSUTF32StringEncoding];
// length:8 capacity:10 bytes:<e4b88061 e4bda032>
NSData *data_UTF8 = [string dataUsingEncoding:NSUTF8StringEncoding];
// length:10 capacity:12 bytes:<fffe004e 6100604f 3200> 其中ff fe標(biāo)識大小端
NSData *data_UTF16 = [string dataUsingEncoding:NSUTF16StringEncoding];
// length:20 capacity:25 bytes:<fffe0000 004e0000 61000000 604f0000 32000000>
NSData *data_UTF32 = [string dataUsingEncoding:NSUTF32StringEncoding];
下面的圖都是查看了內(nèi)存內(nèi)容,首先是NSString
實例的內(nèi)存:
NSString存儲Unicode碼.png
UTF8 編碼后字符指針指向的內(nèi)存:
NSString_UTF8.png
UTF16 編碼后字符指針指向的內(nèi)存:
NSString_UTF16.png
UTF32 編碼后字符指針指向的內(nèi)存:
NSString_UTF32.png