关于NSString中的Emoji表情

NSString的length是怎么计算的?

苹果API文档是这样解释NSString的length方法:返回UTF-16编码单元(码元)的个数。

因此我们猜测NSString底层是使用UTF-16编码存储字符数据的,那何为UTF-16?

UTF-16是Unicode字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为 "storage format")的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。

作者:人生看淡不服就干
链接:https://www.jianshu.com/p/c5675da0d333
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。

通过UTF-16的定义,我们知道英文字母和一般汉字在UTF-16中用两个字节表示,即占一个码元,而一般的Emoji表情用四个字节表示,即占两个码元。所以英文字母和汉字在NSString中的length为1,而一般的Emoji表情在NSString中length为2。

一个复杂表情到底能有多长?

NSString* str = @"‍‍‍?‍?‍?‍?";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"emoji str-len:%d data-len:%d",str.length,data.length);

输出

emoji str-len:11 data-len:25

为何一个表情的长度能有11?

查看表情编码地址:https://apps.timwhitlock.info/unicode/inspect

通过分析,这个复杂表情其实是由四个小表情(两男两女)和三个连接符号组合出来的:

  • 每个小表情在UTF-16中占四个字节,即2个码元
  • 每个连接符号在UTF-16中占两个字节,即1个码元。

所以,在NSString中length为 4*2 + 3*1 = 11 (UTF-16码元个数)

但是当把NSString转换成UTF-8格式的NSData时,数据是这样存储的:

  • 每个小表情在UTF-8中占四个字节
  • 每个连接符号在UTF-8中占三个字节

所以转成NSData后的存储总长度为 4*4 + 3*3 = 25 (字节个数)。

补充:这种组合出来的复杂表情是苹果自己定义的,不属于Unicode编码范围,但每个小表情属于Unicode编码范围,所以将此表情发给安卓端,会被显示成多个连续的小表情。而连接符本身显示出来不占宽度,所以跟没有连接符效果一样。

如何完整的删掉一个复杂表情?

NSString* str = @"a问问‍‍‍?‍?‍?‍?";
NSRange range = [str rangeOfComposedCharacterSequenceAtIndex:str.length-1];
str = [str substringToIndex:range.location];
NSLog(@"emoji location:%d len:%d str:%@",range.location,range.length,str);

输出

emoj location:3 len:11 str:a问问



来源:简书 https://www.jianshu.com/p/c5675da0d333

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值