Каковы плюсы и минусы использования UTF-8 в отличие от чего-то более высокого, такого как UTF-16 или UTF-32?
Альберт Реншоу
4
NSData не заботится о том, является ли это UTF-8 или UTF-16 или UTF-32. Есть две проблемы: одна, UTF-16 и UTF-32 должны иметь правильный порядок байтов. Во-вторых, тот, кто преобразует его обратно в NSString *, должен знать кодировку и часто будет использовать кодировку UTF-8. Как правило, UTF-8, скорее всего, будет обрабатываться правильно.
gnasher729
1
@bendytree на самом деле это не так, -dataUsingEncoding: вернет строку, не заканчивающуюся нулем, что и требуется для stringWithUTF8String: вы обязаны читать память, которая вам не нужна. Что преобразует его обратно: -initWithData: encoding :.
Психо
1
@ Альберт Реншоу в настоящее время (без гарантий того, что так и останется) NSStringиспользует UTF-16 для внутреннего использования, поэтому возможен небольшой выигрыш в производительности, поскольку ему не нужно выполнять преобразование UTF-16 <-> UTF-8. Лично мы предпочитаем (как подсказывает @ gnasher729) надежность над производительностью и везде используем UTF-8.
Какой-то разработчик
66
NSString*str =@"helowrld";// This converts the string to an NSData objectNSData*data =[str dataUsingEncoding:NSUTF8StringEncoding];
Ага. dataUsingEncoding:не возвращает данные с нулевым символом в конце Только UTF8Stringи другие методы, которые возвращают строку C, возвращают строку с нулевым символом в конце.
Питер Хоси
@PeterHosey у тебя есть источник для этого? Мне трудно найти это в любых документах.
shortstuffsushi
1
Благодаря @PeterHosey, Документы вы связаны там же явно указать отсутствие прекращения NULL - (note that the data returned by dataUsingEncoding:allowLossyConversion: is not a strict C-string since it does not have a NULL terminator). Должно быть, я пропустил это раньше. Я обязательно напишу что-нибудь в будущем, хотя.
shortstuffsushi
1
(Для тех, кто интересуется: цитата shortstuffsushi под cStringUsingEncoding:. Я искал под dataUsingEncoding:.)
Питер Хоси
20
В случае появления Swift Developer,
конфертировать из NSString / String в NSData
var _nsdata = _nsstring.dataUsingEncoding(NSUTF8StringEncoding)
let str ="test string"
let data =NSKeyedArchiver.archivedData(withRootObject: str)
let thatStr =NSKeyedUnarchiver.unarchiveObject(with: data) as!String
Вероятно, интенсивно использует процессор по сравнению с другими методами, но очень полезно, если вы постоянно обращаетесь к файловой системе
Стивен Дж
10
Прежде всего, вы должны использовать dataUsingEncoding:вместо прохождения UTF8String. Вы используете только UTF8Stringтогда, когда вам нужноC строка в этой кодировке.
Тогда UTF-16просто пройдите NSUnicodeStringEncodingвместо NSUTF8StringEncodingвашего dataUsingEncoding:сообщения.
Этот ответ неверен, если strсодержит кодовые точки больше 127. Это потому, что str.lengthдает количество символов Юникода, а не количество байтов. Например, если strесть @"にほんご", str.lengthдает 4, а на str.UTF8Stringсамом деле содержит 12 байтов. Даже если вы замените str.lengthна strlen(str.UTF8String), это все равно будет неправильно для случая, когда strсодержит символ NULL, например @"にほ\0んご".
Панг
Созданный таким образом объект NSData выбрасывает исключение при использовании с [NSJSONSerialization JSONObjectWithData: параметры данных: NSJSONReadingMutableLeaves error: & error];
NSString
использует UTF-16 для внутреннего использования, поэтому возможен небольшой выигрыш в производительности, поскольку ему не нужно выполнять преобразование UTF-16 <-> UTF-8. Лично мы предпочитаем (как подсказывает @ gnasher729) надежность над производительностью и везде используем UTF-8.Вы можете взять ссылку по этой ссылке
источник
NSData *data = [@"helowrld" dataUsingEncoding:NSUTF8StringEncoding];
Делать:
тогда не стесняйтесь продолжать
NSJSONSerialization:JSONObjectWithData
.Исправление к ответу относительно NULL-терминатора
После комментариев, официальной документации и проверок этот ответ был обновлен в отношении удаления предполагаемого терминатора NULL:
Как задокументировано dataUsingEncoding :
Как задокументировано getCString: maxLength: encoding: и cStringUsingEncoding ::
источник
dataUsingEncoding:
не возвращает данные с нулевым символом в конце ТолькоUTF8String
и другие методы, которые возвращают строку C, возвращают строку с нулевым символом в конце.(note that the data returned by dataUsingEncoding:allowLossyConversion: is not a strict C-string since it does not have a NULL terminator)
. Должно быть, я пропустил это раньше. Я обязательно напишу что-нибудь в будущем, хотя.cStringUsingEncoding:
. Я искал подdataUsingEncoding:
.)В случае появления Swift Developer,
конфертировать из NSString / String в NSData
источник
Objective-C:
Swift:
источник
Прежде всего, вы должны использовать
dataUsingEncoding:
вместо прохожденияUTF8String
. Вы используете толькоUTF8String
тогда, когда вам нужноC
строка в этой кодировке.Тогда
UTF-16
просто пройдитеNSUnicodeStringEncoding
вместоNSUTF8StringEncoding
вашегоdataUsingEncoding:
сообщения.источник
Для Swift 3 вы будете в основном конвертировать из
String
вData
.источник
источник
str
содержит кодовые точки больше 127. Это потому, чтоstr.length
дает количество символов Юникода, а не количество байтов. Например, еслиstr
есть@"にほんご"
,str.length
дает 4, а наstr.UTF8String
самом деле содержит 12 байтов. Даже если вы заменитеstr.length
наstrlen(str.UTF8String)
, это все равно будет неправильно для случая, когдаstr
содержит символ NULL, например@"にほ\0んご"
.Objective-C:
NSString to NSData:
NSData to NSString:
Swift:
Строка для данных:
Данные в строку:
источник
источник
Objective-C
стриж
источник