これは、エスケープ シーケンス\Uxxxxxxxx がコンパイラによって評価され、対応する Unicode コード ポイントに置き換えられるためです。次に、メソッドstringWithFormat:がフォーマット指定子%iを の 10 進数表現に置き換えるときi。最後の文字列は、 に対応する\Uxxxxxxxx文字と を表す文字を連結したものiです。stringWithFormat:文字を他の文字に置き換えます。既存の文字は変更されません。
しかし問題は、ここでコンパイラが不完全なエスケープ シーケンスを認識していることです。そのため、文字列を生成できず、エラーが発生します。
解決策は、実行時に文字 (単純な整数値) を生成し、それを使用して文字列を作成すること+[NSString stringWithCharacters:length]です。
NSStringしかし、ヘッダーを調べると、がその文字を としてunichar定義されている、つまり 16 ビット長の値として格納していることがわかりますがunsigned short、Unicode コード ポイントU+1F430() には少なくとも 17 ビットが必要です。
そのため、単一のunichar文字を使用してそのコード ポイントを表すことはできません。しかし、心配する必要はありません。2 つの文字を使用して表すことができます。
迷った?解説はこちら!Unicode は文字を定義しません。範囲内の任意の整数値であるコード ポイントを定義しますU+0000– U+10FFFF. 次に、実装は、文字を使用してそれらのコード ポイントを表す方法を決定します。実装は、すべての有効なコード ポイントを表すことができる限り、必要な任意のデータ型を文字として使用できます。最も簡単な解決策は、32 ビット長の整数を使用することですが、使用するコード ポイントのほとんどが最初の Unicode プラン ( U+0000– U+FFFF) にあるため、大量のメモリが必要になります。そのため、 16 ビット長の文字を使用する UTF-16 エンコーディングNSStringでコード ポイントを格納します。
UTF-16 では、それ以降のすべてのコード ポイントはU+FFFF、範囲内の文字のペア (サロゲート ペアと呼ばれます) を使用して格納されます(対応するコード ポイントは、Unicode 標準で明示的に予約されています)。0xD8000xDFFF
結論として、有効な Unicode コード ポイントは、1 文字または 2unichar文字を使用して表すことができます。その方法はそこに記載されています。そして、ここに簡単な実装があります:
static NSString *stringWithCodePoint(uint32_t codePoint)
{
// NOTE: As I edited the answer, you'll find a simpler implementation of
// this function below
unichar characters[2];
NSUInteger length;
if ( codePoint <= 0xD7FF || (codePoint >= 0xE000 && codePoint <= 0xFFFF) ) {
characters[0] = codePoint;
length = 1;
}
if ( codePoint >= 0x10000 && codePoint <= 0x10ffff ) {
codePoint -= 0x10000;
characters[0] = 0xD800 + (codePoint >> 10);
characters[1] = 0xDC00 + (codePoint & 0x3ff);
length = 2;
}
else {
length = 0; // invalid code point
}
return [NSString stringWithCharacters:characters length:length];
}
任意の有効なコード ポイントから文字列を生成できるようになったので、前に記述した関数を使用するようにコードを更新する必要があります。
for (int i = 0; i < 10; i++)
[someArray addObject:stringWithCodePoint(0x0001F430 + i)];
編集:NSStringコードポイントから取得するためのより簡単な方法を見つけました。-[NSString initWithBytes:length:encoding:]およびNSUTF32StringEncodingエンコーディングを使用して機能します。
static NSString *stringWithCodePoint(uint32_t codePoint)
{
NSString *string = [[NSString alloc] initWithBytes:&codePoint length:4 encoding:NSUTF32StringEncoding];
// You may remove the next 3 lines if you use ARC
#if ! __has_feature(objc_arc)
[string autorelease];
#endif
return string;
}