Creating Mutable String Objects

String Services includes only a handful of functions for creating mutable CFString objects. The reason for this much smaller set is obvious. Because these are mutable objects, you can modify them after you create them with the functions described in Manipulating Mutable String Objects.

There are two basic functions for creating mutable CFString objects. The CFStringCreateMutable function creates an "empty" object; the CFStringCreateMutableCopy makes a mutable copy of an immutable CFString object. Listing 5 illustrates the latter function and shows a character being appended to the created object:

Listing 5 Creating a mutable copy of a CFString object
const UniChar u[] = {'5', '+', '*', `d', 'x', '4', 'Q', '?'}; CFMutableStringRef str; str = CFStringCreateMutableCopy(alloc, 0, CFSTR("abc")); CFStringAppendCharacters(str, &u[3], 1); CFRelease(str);

The second parameter of both functions is a CFIndex value named maxLength . This value specifies the maximum numbers of characters in the string and allows the created object to optimize its storage and catch errors if too many characters are inserted. If zero is specified for this parameter (as above), the string can grow to any size.

Mutable Strings With Client-Owned Buffers

When you create most Core Foundation objects, the object takes the initializing data you provide and stores that data internally. String Services allows some exceptions to this behavior, and for mutable CFString objects that exception is the CFStringCreateMutableWithExternalCharactersNoCopy function. This function creates a mutable CFString object whose backing store is some Unicode buffer that you create and own. You can test and manipulate this buffer independently of the object.

Listing 6 shows how to create such a cheap mutable CFString "wrapper" for your character buffer.

Listing 6 Creating a mutable CFString object with independent backing store
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... ")); CFStringAppendPascalString(mutStr, "\pA pascal string. ", CFStringGetSystemEncoding()); CFStringAppendFormat(mutStr, NULL, CFSTR("%d %4.2f %@..."), 42, -3.14, CFSTR("Hello")); CFRelease(mutStr); free(myBuffer); }

The third and fourth parameters in the creation function specify the number of characters in the buffer and the buffer capacity; as with the other mutable creation functions, if the capacity parameter is zero, no limit is placed on growth. The final parameter, externalCharsAllocator , specifies the CFAllocator object to use for reallocating the buffer when editing takes place and for deallocating the buffer when the CFString object is deallocated. In the above example, kCFAllocatorNull is specified, which tells the object that the client assumes responsibility for these actions. If you specified an allocator object to use, such as NULL for the default allocator, there is usually no need to worry about reallocation or deallocation of the buffer.

The example illustrates how you can modify the contents of the buffer with CFString functions. You can also modify the contents of the buffer directly, but if you do so, you must notify the mutable CFString "wrapper" object with the CFStringSetExternalCharactersNoCopy function. You can also substitute an entirely different buffer with this function because it makes the mutable CFString object point directly at the specified UniChar array as its backing store. (However, the CFString object must have been created with the CFStringCreateMutableWithExternalCharactersNoCopy function.) The CFStringSetExternalCharactersNoCopy function does not free the previous buffer.

Using these functions comes at a cost because some CFString optimizations are invalidated. For example, mutable CFString objects can no longer use a gap for editing, and they cannot optimize storage by using 8-bit characters.


© 1999 Apple Computer, Inc. – (Last Updated 07 September 99)