2012-06-28 321 views
1

我的問題如下。我想封裝一個NSMutableData對象的NSString。但我想與其他項目一起做,而不是先將它封裝到NSData中。這畢竟只是字節而已?將NSString轉換爲NSMutableData而不轉換爲NSData

我最後NSMutableData對象看起來像

[header | stringLength | NSString] 

其中header是char和stringLength是一個無符號短。 我建立這樣

unsigned short stringLength = myString.length; 
NSMutableData* nData = [NSMutableData dataWithBytes:(const void*)&header length:sizeof(char)]; 
[nData appendBytes:(const void*)&dataLength length:sizeof(unsigned short)]; 
[nData appendBytes:(const void*)myString length:stringLength]; 

我的包我會再發這在gkSession並在另一端我會提取刺痛lenght然後字符串本身:

NSString* temp = [NSString alloc]; 
[data getBytes:(void*)&temp range:NSMakeRange(sizeof(char)+sizeof(unsigned short), stringLenght)]; 

對於一些原因,這給我不好的內存訪問。我懷疑myString.length沒有達到我期望的水平。你有什麼提示嗎?提前致謝。

回答

1

這行不正確:

[nData appendBytes:(const void*)myString length:stringLength]; 

這是編碼底層NSString結構(其是大於stringLength)的第一部分。

你是什麼意思是:

[nData appendBytes:[myString UTF8String] 
      length:[myString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; 

length是字符數。這可能遠遠小於多字節字符的字節數。正如附註:如果您可以將長度縮短爲1個字節(0-255),那麼該編碼稱爲Pascal字符串,CFString可以原生處理該編碼(請參閱CFStringGetPascalString())。不是你通常想要做的,但有趣的。這對於CFStringCreateWithPascalStringNoCopy()尤其好,因爲您可以完全避免內存複製操作。這主要是爲了傳統的支持,我不會跳過任何箍來使用它,但有時它很方便。

+0

感謝羅!我現在的下一個問題是:我怎樣才能安全地解開字符串?我將它打包爲一個UTF8String,但當我簡單地執行'[data getBytes:(void *)tmpString range:NSMakeRange(rangeBegin,rangeLength)];'時,我得到一個異常終止信號。我將'tmpString'聲明爲'NSMutableString * tmpString = [NSMutableString stringWithCapacity:rangeLength];'。這可能是因爲編碼? 'tmpString'期望填充什麼類型的編碼? – ticofab

+1

我想我找到了方法:首先在通用緩衝區中轉儲所有內容,然後使用'[[NSString alloc] initWithBytes:(const void *)buffer length:dL encoding:NSUTF8StringEncoding];'獲取原始字符串。再次感謝你的幫助! – ticofab