A particularly useful feature of Collection Services is the capability for applying a program-defined function to each value in a collection object. This applier function must conform to a prototype defined for each collection type. You must specify a pointer to this function in the Collection Services function (of the form
CF
Type
ApplyFunction
) that invokes it on each contained value.
Listing 10 provides a simple example that applies a character-counting function to the CFString objects stored in a CFArray object. This function is of the type
CFArrayApplierFunction
. This prototype has two parameters: the first is a value in the array (or a pointer to that value) and the second is some program-defined value (or a pointer to that value).
Listing 10 Applying a function to an array
void countCharacters(const void *val, void *context) { CFStringRef str = (CFStringRef)val; CFIndex *cnt = (CFIndex *)context; CFIndex numchars = CFStringGetLength(str); *cnt += numchars; } void countCharsInArray() { CFStringRef strs[3]; CFArrayRef anArray; CFIndex count=0; strs[0] = CFSTR("String One"); strs[1] = CFSTR("String Two"); strs[2] = CFSTR("String Three"); anArray = CFArrayCreate(NULL, (void *)strs, 3, &kCFTypeArrayCallBacks); CFArrayApplyFunction(anArray, CFRangeMake(0,CFArrayGetCount(anArray)), countCharacters, &count); printf("The number of characters in the array is %d", count); CFRelease(anArray); }
ImportantIt is unsafe to change the contents of a mutable collection while an applier function is being applied to its values. It is better to somehow record where changes need to be made and then make them after the applier function finishes iterating over the collection.