Создание и копирование строк

Строковые объекты дают Вам множество способов создать объекты CFString — из постоянных строк, из буферов, от отформатированных строк, и при помощи существующих объектов CFString. Следующие разделы описывают каждый из этих методов.

Некоторые функции, возвращающие ссылки на объекты CFString, описаны в другом месте. CFStringCreateWithBytes функция описана в Преобразовании Между Строковыми Кодировками. Раздел Handling External Representations of Strings описывает CFStringCreateFromExternalRepresentation функция.

Создание объектов CFString от постоянных строк

Самый простой способ создать неизменные объекты CFString состоит в том, чтобы использовать CFSTR макрос. Параметром макроса должна быть постоянная строка времени компиляции — текст, включенный в кавычки. CFSTR возвращает ссылку на объект CFString.

Вот пример:

CFStringRef hello = CFSTR("Hello, world.");

Возвращенный CFString имеет следующую семантику:

Если существует два или больше точных экземпляра постоянной строки в исполнимой программе, в некоторых случаях только один мог бы быть сохранен. Общее использование CFSTR макрос находится в создании отформатированных строк (см. Строковые Объекты Создания От Отформатированных строк для получения дополнительной информации).

Создание объектов CFString от строковых буферов

Общий метод для создания объекта CFString должен вызвать функции, берущие буферы символа C (или указатели строк) как «источник» для объекта. Эти функции являются дубликатами функций, преобразовывающих объекты CFString в струны до; посмотрите Доступ к Содержанию Строковых Объектов для больше на этих функциях.

Эти функции прибывают в два варианта. Один набор функций копирует буфер во внутреннюю память создаваемого объекта CFString. Как только Вы создаете объект, Вы свободны избавиться от буфера. Связанные функции создают объекты CFString из буферов струны до (CFStringCreateWithCString) и от Unicode представляют буферы в виде строки (CFStringCreateWithCharacters). Последняя функция берет дополнительный параметр для счетчика символов, но не включает параметр кодирования.

Параллельный набор функций имеет соответствующие имена тот конец с NoCopy. Эти функции также создают объекты CFString из буфера пользовательской предоставленной строки, но они не всегда копируют буфер во внутреннюю память объекта. Они пытаются, но, как гарантируют, не возьмут предоставленный указатель как есть, с помощью буфера в качестве запоминающего устройства, не копируя данные. Очевидно, необходимо гарантировать, чтобы Вы не освобождали буфер, в то время как существует CFString. Символьные данные никогда не должны быть на штабеле или быть данными со временем жизни, которое Вы не можете гарантировать.

На практике, они NoCopy функции полезны в ограниченном количестве обстоятельств:

NoCopy функции включают дополнительный параметр (contentsDeallocator) для передачи ссылки на объект CFAllocator, использующийся для освобождения буфера, когда это больше не необходимо. Если объект CFAllocator по умолчанию достаточен с этой целью, можно передать NULL. Если Вы не хотите объект CFString освободить буфер, передачу kCFAllocatorNull.

Перечисление 1 показывает создание объекта CFString с CFStringCreateWithCStringNoCopy функция:

Перечисление 1  , Создающее CFString, возражает с функцией NoCopy

const char *bytes;
CFStringRef str;
bytes = CFAllocatorAllocate(CFAllocatorGetDefault(), 6, 0);
strcpy(bytes, "Hello");
str = CFStringCreateWithCStringNoCopy(NULL, bytes,
    kCFStringEncodingMacRoman, NULL);
/* do something with str here...*/
CFRelease(str); /* default allocator also frees bytes */

Можно также создать непостоянные объекты CFString с исходными буферами, которыми Вы управляете полностью; посмотрите Непостоянные Строки С Клиентскими Буферами для больше по этому вопросу.

Создание строковых объектов от отформатированных строк

Строковые объекты включают функции, создающие объекты CFString из отформатированных строк — строковое слияние printf- спецификаторы стиля для замены значениями переменных в строку, после преобразования их (если необходимый) к символьным данным. Спецификаторы формата строки определяются в Спецификаторах Формата строки. Отформатированные строки полезны, когда необходимо вывести на экран информацию, которая может иметь изменяемые элементы. Например, Вы, возможно, должны были бы использовать эти функции при подъеме диалогового окна для показа прогресса работы, такой как “Копирование файла x y”.

CFStringCreateWithFormat функция создает объект CFString из простой отформатированной строки, как показано в Перечислении 2.

Перечисление 2  , Создающее CFString, возражает от отформатированной строки

CFStringRef PrintGross(CFStringRef employeeName, UInt8 hours, float wage) {
    return CFStringCreateWithFormat(NULL, NULL, CFSTR(“Employee %@
    earned $%.2f this week.”), employeeName, hours * wage);
}

Первый параметр, как обычно, указывает объект-распределитель для использования (NULL средние значения используют объект CFAllocator по умолчанию). Второй параметр для зависимых от локали параметров формата, таких как тысяча и десятичные разделители; это в настоящее время не используется. Остающиеся параметры для строки формата и значений переменных.

Как отмечалось ранее, строка формата имеет printf- спецификаторы стиля, встроенные в него (например, “%d %s %2.2f”). Базовая Основа представляет несколько расширений этого соглашения. Каждый %@ спецификатор (показанный в Перечислении 2), который указывает любой Базовый объект Основы. Другой новый спецификатор указывает порядок аргументов. Этот спецификатор принимает форму n$ где n является номером заказа параметра после строки. Эта функция порядка аргументов полезна, когда Вы хотите локализовать целые предложения или даже абзацы на другие языки, не волнуясь о порядке параметров, которые могли бы варьироваться от одного языка до другого.

Например, функция выше привела бы к строке, такой как “заработанные 1 012,32$ Джона Доу на этой неделе”. Но на другом языке грамматически надлежащий способ выразить то же предложение мог бы быть (примерно переведен) “1 012,32$, был заработан Джоном Доу на этой неделе”. Вы не должны были бы вызывать CFStringCreateWithFormat снова с параметрами в различном порядке. Вместо этого у Вас был бы вызов функции, который был похож на это:

return CFStringCreateWithFormat(NULL, NULL, CFSTR(“$%2$.2f was earned by
    employee %1$@.”), employeeName, hours * wage);

Конечно, сама строка не была бы трудно кодирована, но будет загружена из файла (например, список свойств XML или список свойств OpenStep ASCII), который содержит локализованные строки и их переводы.

Другая функция CFString, CFStringCreateWithFormatAndArguments, берет список аргумента переменной (vararg) а также строка формата. Эта функция позволяет форматирование varargs передал в Вашу функцию. Перечисление 3 показывает, как оно могло бы использоваться:

Перечисление 3  , Создающее CFString из списка аргумента переменной

void show(CFStringRef formatString, ...) {
    CFStringRef resultString;
    CFDataRef data;
    va_list argList;
 
    va_start(argList, formatString);
    resultString = CFStringCreateWithFormatAndArguments(NULL, NULL,
        formatString, argList);
    va_end(argList);
 
    data = CFStringCreateExternalRepresentation(NULL, resultString,
        kCFStringEncodingMacRoman, '?');
 
    if (data != NULL) {
        printf ("%.*s\n\n", (int)CFDataGetLength(data),
            CFDataGetBytePtr(data));
        CFRelease(data);
    }
 
    CFRelease(resultString);
}

Создание непостоянных строковых объектов

Строковые объекты включают только ряд функций для создания непостоянных объектов CFString. Причина этого намного меньшего набора очевидна. Поскольку это непостоянные объекты, можно изменить их после создания их с функциями, описанными в Управлении Непостоянными Строковыми Объектами.

Существует две основных функции для создания непостоянных объектов CFString. CFStringCreateMutable функция создает «пустой» объект; CFStringCreateMutableCopy делает непостоянную копию неизменного объекта CFString. Перечисление 4 иллюстрирует последнюю функцию и показывает символ, добавляемый созданному объекту:

Перечисление 4  , Создающее непостоянную копию объекта CFString

const UniChar u[] = {'5', '+', '*', ‘d’, 'x', '4', 'Q', '?'};
CFMutableStringRef str;
 
str = CFStringCreateMutableCopy(alloc, 0, CFSTR("abc"));
CFStringAppendCharacters(str, &u[3], 1);
CFRelease(str);

Второй параметр обеих функций является a CFIndex значение, названное maxLength. Если слишком много символов вставляются, это значение указывает максимальные количества символов в строке и позволяет созданному объекту оптимизировать свое хранение и фиксировать ошибки. Если 0 указан для этого параметра (как выше), строка может расти до любого размера.

Непостоянные строки с Клиентскими буферами

При создании большинства Базовых объектов Основы объект берет данные инициализации, которые Вы предоставляете, и хранит те данные внутренне. Строковые объекты позволяют некоторые исключения этому поведению, и для непостоянного CFString возражает, что исключение CFStringCreateMutableWithExternalCharactersNoCopy функция. Эта функция создает непостоянный объект CFString, запоминающее устройство которого является некоторым буфером Unicode, который Вы создаете и владеете. Можно протестировать и управлять этим буфером независимо от объекта.

Перечисление 5 показывает, как создать такую дешевую непостоянную «обертку» CFString для Вашего символьного буфера.

Перечисление 5  , Создающее непостоянный CFString, возражает с независимым запоминающим устройством

void stringWithExternalContentsExample(void) {
#define BufferSize 1000
    CFMutableStringRef mutStr;
    UniChar *myBuffer;
 
    myBuffer = malloc(BufferSize * sizeof(UniChar));
 
    mutStr = CFStringCreateMutableWithExternalCharactersNoCopy(NULL, myBuffer, 0, BufferSize, kCFAllocatorNull);
    CFStringAppend(mutStr, CFSTR("Appended string... "));
    CFStringAppend(mutStr, CFSTR("More stuff... "));
    CFStringAppendFormat(mutStr, NULL, CFSTR("%d %4.2f %@..."), 42, -3.14, CFSTR("Hello"));
 
    CFRelease(mutStr);
    free(myBuffer);
}

Третьи и четвертые параметры в функции создания указывают число символов в буфере и буферной емкости. Заключительный параметр, externalCharsAllocator, указывает объект CFAllocator использовать для перераспределения буфера, когда редактирование имеет место и для освобождения буфера, когда освобожден объект CFString. В вышеупомянутом примере, kCFAllocatorNull указан, который говорит объекту, что клиент принимает на себя ответственность за эти действия. Если Вы указали объект-распределитель для использования, такой как NULL для средства выделения по умолчанию обычно нет никакой потребности волноваться о перераспределении или освобождении буфера.

Пример иллюстрирует, как можно изменить содержание буфера с функциями CFString. Можно также изменить содержание буфера непосредственно, но если Вы делаете так, необходимо уведомить непостоянный объект «обертки» CFString с CFStringSetExternalCharactersNoCopy функция. Можно также заменить полностью различным буфером с этой функцией, потому что она высказывает непостоянное мнение объекта CFString непосредственно в указанном UniChar выстройте как его запоминающее устройство. (Однако объект CFString, должно быть, был создан с CFStringCreateMutableWithExternalCharactersNoCopy функция.) CFStringSetExternalCharactersNoCopy функция не освобождает предыдущий буфер.

Используя эти функции прибывает в стоимость, потому что некоторая оптимизация CFString лишена законной силы. Например, непостоянные объекты CFString больше не могут использовать разрыв для редактирования, и они не могут оптимизировать хранение при помощи 8-разрядных символов.