[关闭]
@qidiandasheng 2017-04-26T16:08:26.000000Z 字数 2389 阅读 3544

iOS编码问题

iOS理论


NSDictionary打印不出中文

NSDictionary和NSArray在打印的时候使用的是Unicode编码。所以需要解码成中文。

代码如下:

  1. NSDictionary *dic = @{
  2. @"name": @"我是中文字符",
  3. };
  4. NSString *dicStr = [NSString stringWithFormat:@"%@",dic];
  5. //const char *cstring = [a cStringUsingEncoding:NSUTF8StringEncoding];
  6. const char *cstring = [dicStr UTF8String];
  7. NSString *trans = [[NSString alloc] initWithCString:cstring encoding:NSNonLossyASCIIStringEncoding];
  8. NSLog(@"%@",trans);

Unicode的encode和decode:

  1. //encode
  2. NSString *yourtext = @"我是中文字符";
  3. NSData *dataenc = [yourtext dataUsingEncoding:NSNonLossyASCIIStringEncoding];
  4. NSString *encodevalue = [[NSString alloc] initWithData:dataenc encoding:NSUTF8StringEncoding];
  5. //decode
  6. NSDictionary *dic = @{
  7. @"name": @"我是中文字符",
  8. };
  9. NSString *yourtext2 = [NSString stringWithFormat:@"%@",dic];
  10. NSData *data = [yourtext2 dataUsingEncoding:NSUTF8StringEncoding];
  11. NSString *decodevalue = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding];

如果只想在LLDB中输出中文而已的话,可以使用Chisel-LLDB命令插件

Url编码

  1. //url encode
  2. NSString *urlString = [NSString stringWithFormat:@"http://www.xxxx.com/?param=%@",@"我是中文字符"];
  3. urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
  4. //url decode
  5. NSString *urlString = @"http://www.xxxx.com/?param=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87%E5%AD%97%E7%AC%A6";
  6. urlString = [urlString stringByRemovingPercentEncoding];

关于字符集和字符编码的概念

其实上面所说的url编码才是真正的UTF8编码,只是在每个字节前加上%而已。而我们上文中所说的[[NSString alloc] initWithData:dataenc encoding:NSUTF8StringEncoding]其实只是Unicode编码,并不是真正的UTF8编码。
具体的原理可以参考阮一峰的关于URL编码

我们也可以使用Unicode编码转换工具来查看编码,这里以字符为例:

  1. 中文转unicode \u5b57\u7b26
  2. 中文转UTF-8: 字符
  3. url编码(utf-8): %e5%ad%97%e7%ac%a6

我们看到其实前两种只有前缀不一样\u&#x,其实他们后面的值都是目标字符的 Unicode code point;以「&#」开头的后接十进制数字,以「&#x」开头的后接十六进制数字。

Unicode即为编码字符集,即用一个编码值code point来表示一个字符在字库中的位置。而UTF-8(字符编码)只是对Unicode的一种实现方式。UTF-8如果要找到对应的字符还是需要转换回Unicode,然后根据编码值从字库里找到字符。

字符编码(包括UTF-8,UTF-16等):即为编码字符集和实际存储数值之间的转换关系。那么既然Unicode能表示所有的字符,那么为什么还需要字符编码转换呢?

这里就涉及到Unicode两个严重的问题,第一个问题是,如何才能区别Unicode和ASCII(ASCII码一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0)?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?比如的Unicode十六进制为7b26,二进制为111101100100110,占用两个字节。怎么区分二进制111101100100110不是两个字符呢呢?

第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

字符编码就能解决以上两个问题,字符编码就是把Unicode进行转换,然后能标记当前字符为几字节字符。具体原理可参考十分钟搞清字符集和字符编码字符编码笔记:ASCII,Unicode和UTF-8。文章中还介绍了UTF-8的编码实现方法。

参考

从NSDictionary打印不出中文开始
关于URL编码
字符编码笔记:ASCII,Unicode和UTF-8
十分钟搞清字符集和字符编码

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注