Unicode 转 NSString

5
我有一堆Unicode字符被封装到NSNumber中,就像这样:
@(0x1f4de),    // EntypoIconTypePhone
@(0x1f4f1),    // EntypoIconTypeMobile
@(0xe789),     // EntypoIconTypeMouse
@(0xe723),     // EntypoIconTypeAddress
@(0x2709),     // EntypoIconTypeMail
@(0x1f53f),    // EntypoIconTypePaperPlane
@(0x270e),     // EntypoIconTypePencil

这些是来自Entypo字体的图标(强烈推荐)。

这是我使用的代码,用于从Unicode创建NSString:

NSNumber *u = self.unicodeLookup[type];

int unicode = [u intValue];
UniChar chars[] = {unicode};

NSString *string = [[NSString alloc] initWithCharacters:chars length:sizeof(chars) / sizeof(UniChar)];

我发现有些图标可以正常创建,但不是全部;据我观察,那些由5个数字组成的Unicode码无法正确创建。
例如,以下图标可以正常创建:
@(0xe723),     // EntypoIconTypeAddress
@(0x2709),     // EntypoIconTypeMail

但是这些不行:
@(0x1f4de),    // EntypoIconTypePhone
@(0x1f4f1),    // EntypoIconTypeMobile

我相信这是我的转化代码。我不太理解所有这些编码的复杂性。

2个回答

2
如果我使用这个来创建我的字符串,它可以适用于Entypo字体的unicode int值:
int unicode = uniChars[type];

NSString* s = [[NSString alloc] initWithBytes:&unicode length:sizeof(unicode)  encoding:NSUTF32LittleEndianStringEncoding];
uniChars是一个CArray,其中包含int,而不是我之前使用的NSArrayNSNumber。实际上没有理由这样做,两种方法都应该可以工作。 更新: 仍然存在一些Unicode数字的问题。Entypo Social字体字符未显示。与普通图标的区别在于它们都以F开头,并且有4个字符。
0xF300 ,         //   EntypoIconSocialTypeGithub,
0xF301 ,         //   EntypoIconSocialTypeCGithub,
0xF303 ,         //   EntypoIconSocialTypeFlickr,
0xF304 ,         //   EntypoIconSocialTypeCFlickr,

我怀疑编码会不同。


2

如果您使用unichar存储字符常量,而不是NSNumber对象,则编译器本身会告诉您原因:

unichar chars[] = 
{
    0xe723,     // EntypoIconTypeAddress
    0x2709,     // EntypoIconTypeMail
    0x1f4de,    // EntypoIconTypePhone
    0x1f4f1     // EntypoIconTypeMobile
};

Implicit conversion from 'int' to 'unichar' (aka 'unsigned short') changes value from 128222 to 62686
Implicit conversion from 'int' to 'unichar' (aka 'unsigned short') changes value from 128241 to 62705

iOS/OSX内部使用16位unicode字符表示,而0x1f4de和0x1f4f1都是32位,因此您需要将这些字符编码为代理对:

a = 0x1f4de - 0x10000 = 0xf4de
high = a >> 10 = 0x3d
low = a & 0x3ff = 0xde
w1 = high + 0xd800 = 0xd83d
w2 = low + 0xdc00 = 0xdcde

0x1f4de (UTF-32) = 0xd83d 0xdcde (UTF-16)

(请参考维基百科页面

简而言之,您不能使用单个Unicode字符数组,因为您需要知道每个字符编码的长度。


我成功地使用我在第二条评论中提供的代码使您示例中的字符显示出来了。现在唯一的问题是社交字体字符。不过还是谢谢您的建议,我会尝试调整一下看看能否让它们也正常工作。 - Lee Probert
我注意到在使用unichar时会出现警告,但是如果我将数组强制转换为int类型,它就能正常工作。 - Lee Probert
@LeeProbert int 至少总是32位,但 unichar 总是16位。你的选择之一是将字符存储为UTF-32(在 unsigned 的情况下,而不是 unichar),然后使用 [NSString initWithBytes:length:encoding:],编码为 NSUTF32StringEncoding,但是可能需要解决字节序问题(我还没有深入研究)。 - trojanfoe
是的。使用NSUTF32LittleEndianStringEncoding对于那些前面的字符块有所帮助。社交字体是一种不同的字体,但似乎那些0xF***字符不在同一范围内。 - Lee Probert
np,感谢帮助。不管怎样,如果我能使它正常运行,我认为您会喜欢这门课程。 - Lee Probert
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接