By far the most common technique for creating a CFString object is to call functions that take C or Pascal character buffers (or string pointers) as "source" for the object. These functions are the counterparts of functions that convert CFString objects to C or Pascal strings; see Accessing the Contents of String Objects for more on these functions.
These functions come in two varieties. One set of functions copies the buffer into the internal storage of the created CFString object. Once you create the object you are free to dispose of the buffer. Listing 1 shows the creation of a CFString object from a Pascal string buffer with the
CFStringCreateWithPascalString
function.
Listing 1 Creating a CFString object from a Pascal string buffer
const UInt8 somePascalBytes[] = {5, `H', `e', `l', `l', `o'}; CFStringRef str; str = CFStringCreateWithPascalString(NULL, somePascalBytes, kCFStringEncodingMacRoman);
In this example, the
NULL
parameter specifies that the default CFAllocator object should be used to allocate memory for the backing store; the last parameter specifies the encoding of the characters in the buffer. Instead of initializing the
somePascalBytes
array as done in the example above, you can just insert the
\p
control character before the string to designate it a Pascal string (
"\pHello"
).
Related functions create CFString objects from C string buffers (
CFStringCreateWithCString
) and from Unicode string buffers (
CFStringCreateWithCharacters
). The latter function takes an extra parameter for character count but does not include the encoding parameter.
A parallel set of functions have corresponding names that end with NoCopy. These functions also create CFString objects from a user-supplied string buffer but they do not always copy the buffer to the object's internal storage. They try to take the provided pointer as-is, using the buffer as the backing store without copying the data. Obviously you must ensure that you do not free the buffer while the CFString exists. The character data should never be on the stack or be data with a lifetime you cannot guarantee.
In practice, these NoCopy functions are useful in a limited number of circumstances:
kCFAllocatorNull
as the last parameter (see below), when the CFString ceases to exist the buffer is not automatically deallocated. (Often you can use the
CFSTR
macro for the same purpose.)
The NoCopy functions include an extra parameter (
contentsDeallocator
) for passing a reference to a CFAllocator object that is used for deallocating the buffer when it is no longer needed. If the default CFAllocator object is sufficient for this purpose, you can pass
NULL
. If you do not want the CFString object to deallocate the buffer, pass
kCFAllocatorNull
.
Listing 2 shows the creation of a CFString object with the
CFStringCreateWithCStringNoCopy
function:
Listing 2 Creating a CFString object with a NoCopy function
const char *bytes; CFStringRef str; bytes = CFAllocatorAllocate(CFAllocatorGetDefault(), 6, 0); strcpy(bytes, "Hello"); str = CFStringCreateWithCStringNoCopy(NULL, bytes, CFStringGetSystemEncoding(), NULL); /* do something with str here...*/ CFRelease(str); /* default allocator also frees bytes */
ImportantThe CFString objects created by the NoCopy function do not necessarily use the buffer you supply. In some cases the object might free the buffer and use something else; for instance, it may decide to use Unicode encoding internally. CFString objects do not use some encodings internally and so may also free the provided buffer and use their own.
You can also create mutable CFString objects with source buffers that you control entirely; see Mutable Strings With Client-Owned Buffers for more on this matter.