Спецификатор формата NSLog% s находится в системной кодировке, которая, по-видимому, всегда является MacRoman, а не Unicode, поэтому она может отображать только символы в кодировке MacRoman. Лучший вариант с NSLog - просто использовать спецификатор формата собственного объекта% @ и передавать NSString напрямую, а не преобразовывать его в строку C. Если у вас есть только строка C и вы хотите использовать NSLog для отображения сообщения вместо printf или asl, вам придется сделать что-то, как предлагает Дон, чтобы сначала преобразовать строку в объект NSString.
Итак, все они должны отображать ожидаемую строку:
NSString *str = @"你好";
const char *cstr = [str UTF8String];
NSLog(@"%@", str);
printf("%s\n", cstr);
NSLog(@"%@", [NSString stringWithUTF8String:cstr]);
Если вы решили использовать asl, обратите внимание, что, хотя он принимает строки в формате UTF8 и передает правильную кодировку демону syslog (чтобы он правильно отображался в консоли), он отображает строку для визуального кодирования при отображении к терминалу или регистрации в дескрипторе файла, поэтому значения, отличные от ASCII, будут отображаться как экранированные последовательности символов.