2012-08-01 43 views
1

在下面的代碼中,我丟失了字符串中的最後一個字符。從NSData到NSString的轉換將截斷使用多字節UTF8字符的位置

NSString *testString = @"— choose a category —"; 
NSData *testData  = [NSData dataWithBytes:[testString UTF8String] length:[testString length]]; 
NSString *newString  = [[[NSString alloc] initWithData:testData encoding:NSUTF8StringEncoding] autorelease]; 

調試器將顯示有關信息:

(lldb) po testString 
(NSString *) $7 = 0x002ec7f0 — choose a category — 
(lldb) po testData 
(NSData *) $8 = 0x1003d1c0 <e2809420 63686f6f 73652061 20636174 65676f72 79> 
(lldb) po newString 
(NSString *) $9 = 0x09109f50 — choose a category 
(lldb) 

的字節數對應的字符如下:

e2 80 94 | 20 | 63 | 68 | 6f | 6f | 73 | 65 | 20 | 61 | 20 | 63 | 61 | 74 | 65 | 67 | 6f | 72 | 79 | 
EM DASH | sp | c | h | o | o | s | e | sp | a | sp | c | a | t | e | g | o | r | y | sp | EM DASH 

我看到了同樣的問題,我上傳到更長的字符串我服務器,它似乎總是使用多字節UTF8字符的地方。

當我從我的服務器上下載記錄的數據時,unicode字符(尚未被截斷)顯示正確。但我的服務器上的日誌字符串被截斷,表明截斷存在於NSData對象中。

我在這裏做錯了什麼?

回答

0

這是解決方案。這可能會幫助其他人,所以我會把它留在這裏,而不是刪除問題。

NSData dataWithBytes:length:需要得到的字節數組的長度值。這是在NSString被轉換爲空終止的UTF8表示後確定的。

所以轉換爲NSData的正確處理是這樣的:

NSData *testData = [NSData dataWithBytes:[testString UTF8String] length:strlen([testString UTF8String])]; 

爲了避免轉換將TestString的兩倍,這是可以做到:

const char *testStringUTF8 = [testString UTF8String]; 
NSData *testData = [NSData dataWithBytes:testStringUTF8 length:strlen(testStringUTF8)]; 

NSString類引用狀態的C字符串由UTF8String方法返回的「就像返回的對象被釋放」一樣處理,這意味着它是自動釋放的。 (具體措辭見類參考。)