Applying Program-Defined Functions to Collections
A particularly useful feature of collections 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 functions (of the form CF
TypeApplyFunction
)
that invokes it on each contained value.
Listing 1 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 1 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); |
} |
Often an applier function is used to iterate over a mutable collection in order to remove objects matching certain criteria. It is never safe to mutate a collection while an applier function is iterating over it. However, there are some safe ways to use an applier function to mutate a collection:
Mutate after iterating. Use the applied function to record where changes are needed in the collection, and then mutate the collection after an applier function finishes executing.
Mutate the original. If the collection is mutable, make a copy of the collection and use an applier function to iterate over the copy and mutate the original.
Which approach is easier depends on the situation. If the original collection is immutable, then you can use a variation:
Mutate a copy. Make a mutable copy of the collection and use an applier function to iterate over the original and mutate the copy.
Copyright © 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-01-18