生活随笔
收集整理的這篇文章主要介紹了
解决NSData转NSString返回nil的问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在使用initWithData 等方法將 NSData轉換成NSString時, 如果NSData的內容含有非encoding編碼的字符,將會返回nil。
----------SDK文檔如下-------------
- ( instancetype ) initWithData: ( NSData?* ) data? encoding: ( NSStringEncoding ) encoding;
Return Value
An?NSString?object initialized by converting the bytes in?data ?into Unicode characters using?encoding . The returned object may be different from the original receiver. Returns?nil?if the initialization fails for some reason (for example if?data ?does not represent valid data for?encoding ).
-----------------------------
這個結果在很多時候可能并不是我們所希望的,比如在獲取網頁源碼進行分析等方面,如果頁面采用了utf-8編碼,只是含有個別非utf-8字符,我們更希望轉換NSString成功,拋棄(或替換)那些非法字符。
按照utf8格式標準
Unicode/UCS-4 bit數 UTF-8 byte數 范圍(16進制) 0000 ~ 007F 0~7 0 XXX XXXX 1 0x - 7x 0080 ~ 07FF 8~11 110 X XXXX 10 XX XXXX 2 Cx 8x - Dx Bx 0800 ~ FFFF 12~16 1110 XXXX 10 XX XXXX 10 XX XXXX 3 Ex 8x 8x - Ex Bx Bx 1 0000 ~ 1F FFFF 17~21 1111 0 XXX 10 XX XXXX 10 XX XXXX 10 XX XXXX 4 F8 8x 8x 8x 8x - FB Bx Bx Bx Bx? 20 0000 ~ 3FF FFFF 22~26 1111 10 XX 10 XX XXXX 10 XX XXXX 10 XX XXXX 10 XX XXXX 5 FC 8x 8x 8x 8x 8x - FD Bx Bx Bx Bx Bx 400 0000 ~ 7FFF FFFF 27~31 1111 110 X 10 XX XXXX 10 XX XXXX 10 XX XXXX 10 XX XXXX 10 XX XXXX 6
如果一個字節小于0x80,那么他就是一個字符;
如果大于C0小于E0,表示2個字節組成的utf8字符(第一個是110開頭的,第二個是10開頭的);
如果大于E0小于F0,表示3個字節組成的utf8字符(第一個是1110開頭的,第二個是10開頭的,第三個是10開頭的);
以此類推,如果不符合utf-8規則,則表示一個非法字符,只要替換這樣的字符即可。?
實現方法如下(此實現可用但不夠嚴謹,如用于工程中建議進行優化):
[objc] ?view plaincopy
?? ?? -?(NSData ?*)replaceNoUtf 8 :( NSData ?*)data?? {?? ????char ?aa[]?=?{ 'A' , 'A' , 'A' , 'A' , 'A' , 'A' };?????????????????????? ?? ????NSMutableData ?*md?=?[NSMutableData ?dataWithData :data];?? ????int ?loc?=? 0 ;?? ????while (loc?<?[md ?length ])?? ????{?? ????????char ?buffer;?? ????????[md?getBytes :&buffer ?range :NSMakeRange(loc,? 1 )];?? ????????if ((buffer?&? 0 x 8 0 )?==? 0 )?? ????????{?? ????????????loc++;?? ????????????continue ;?? ????????}?? ????????else ? if ((buffer?&? 0 xE 0 )?==? 0 xC 0 )?? ????????{?? ????????????loc++;?? ????????????[md?getBytes :&buffer ?range :NSMakeRange(loc,? 1 )];?? ????????????if ((buffer?&? 0 xC 0 )?==? 0 x 8 0 )?? ????????????{?? ????????????????loc++;?? ????????????????continue ;?? ????????????}?? ????????????loc--;?? ?????????????? ????????????[md?replaceBytesInRange :NSMakeRange(loc,? 1 ) ?withBytes :aa ?length : 1 ];?? ????????????loc++;?? ????????????continue ;?? ????????}?? ????????else ? if ((buffer?&? 0 xF 0 )?==? 0 xE 0 )?? ????????{?? ????????????loc++;?? ????????????[md?getBytes :&buffer ?range :NSMakeRange(loc,? 1 )];?? ????????????if ((buffer?&? 0 xC 0 )?==? 0 x 8 0 )?? ????????????{?? ????????????????loc++;?? ????????????????[md?getBytes :&buffer ?range :NSMakeRange(loc,? 1 )];?? ????????????????if ((buffer?&? 0 xC 0 )?==? 0 x 8 0 )?? ????????????????{?? ????????????????????loc++;?? ????????????????????continue ;?? ????????????????}?? ????????????????loc--;?? ????????????}?? ????????????loc--;?? ?????????????? ????????????[md?replaceBytesInRange :NSMakeRange(loc,? 1 ) ?withBytes :aa ?length : 1 ];?? ????????????loc++;?? ????????????continue ;?? ????????}?? ????????else ?? ????????{?? ?????????????? ????????????[md?replaceBytesInRange :NSMakeRange(loc,? 1 ) ?withBytes :aa ?length : 1 ];?? ????????????loc++;?? ????????????continue ;?? ????????}?? ????}?? ?????? ????return ?md;?? }??
轉換后的NSData就可以正確轉換為NSString了。
*如果是非utf-8編碼,請自行對對應照編碼協議轉換。
總結
以上是生活随笔 為你收集整理的解决NSData转NSString返回nil的问题 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。