@qidiandasheng
2017-04-27T00:08:26.000000Z
字数 2389
阅读 3663
iOS理论
NSDictionary和NSArray在打印的时候使用的是Unicode编码。所以需要解码成中文。
代码如下:
NSDictionary *dic = @{
@"name": @"我是中文字符",
};
NSString *dicStr = [NSString stringWithFormat:@"%@",dic];
//const char *cstring = [a cStringUsingEncoding:NSUTF8StringEncoding];
const char *cstring = [dicStr UTF8String];
NSString *trans = [[NSString alloc] initWithCString:cstring encoding:NSNonLossyASCIIStringEncoding];
NSLog(@"%@",trans);
Unicode的encode和decode:
//encode
NSString *yourtext = @"我是中文字符";
NSData *dataenc = [yourtext dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *encodevalue = [[NSString alloc] initWithData:dataenc encoding:NSUTF8StringEncoding];
//decode
NSDictionary *dic = @{
@"name": @"我是中文字符",
};
NSString *yourtext2 = [NSString stringWithFormat:@"%@",dic];
NSData *data = [yourtext2 dataUsingEncoding:NSUTF8StringEncoding];
NSString *decodevalue = [[NSString alloc] initWithData:data encoding:NSNonLossyASCIIStringEncoding];
如果只想在LLDB中输出中文而已的话,可以使用Chisel-LLDB命令插件。
//url encode
NSString *urlString = [NSString stringWithFormat:@"http://www.xxxx.com/?param=%@",@"我是中文字符"];
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//url decode
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";
urlString = [urlString stringByRemovingPercentEncoding];
其实上面所说的url编码才是真正的UTF8编码,只是在每个字节前加上%而已。而我们上文中所说的[[NSString alloc] initWithData:dataenc encoding:NSUTF8StringEncoding]
其实只是Unicode编码,并不是真正的UTF8编码。
具体的原理可以参考阮一峰的关于URL编码。
我们也可以使用Unicode编码转换工具来查看编码,这里以字符
为例:
中文转unicode: \u5b57\u7b26
中文转UTF-8: 字符
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
十分钟搞清字符集和字符编码