A collection object (or simply, a collection) is a container of discrete values, usually of the same type. A collection can contain other Core Foundation objects, custom data structures, and primitive data values. Contained Core Foundation objects can be of different types. Strictly speaking, "contain" is not an exact term (although it's conceptually useful) because an element of data in a Core Foundation collection can be no larger than the size of a pointer, which varies by processor and compiler. But pointers afford a great deal of flexibility and thus collection objects permit references to Core Foundation objects and pointers to any chunk of data as well as primitive values (such as integers) that take up no more space than a pointer address.
ImportantYou should exercise caution if you use a collection object to store primitive values directly. Because the size of a pointer address on a platform can change over time or can vary among the platforms on which code is expected to run, storing primitive values directly in collections might result in odd behavior, such as the truncation of the values.
All collection objects enable you to access a contained value that satisfies a particular external property. This property, generally referred to as a "key," varies according to the organizing scheme enforced by the type of collection. For example, the key for an array is an integer that specifies position within the collection; on the other hand, a dictionary--for which the term "key" has a more of a conventional meaning--permits any arbitrary value to act as the key for retrieving a contained value. A Core Foundation object retrieved from a collection is not guaranteed to persist because the owning collection might free it, so if you want to hold onto it you should retain or copy it. See Types of Collections for more on the keys of specific collection types.
Core Foundation collection objects automatically handle contained values in similar ways. They maintain weak (that is, pointer) references to the values you put in them, but you define any additional retaining and releasing behavior (including, for example, doing nothing). Most Collection Services types have a set of call back functions that define fundamental operations performed on the elements of that collection. These callbacks are invoked to
Default callbacks are provided for collections that hold Core Foundation objects, but if you have custom data, or if the default callbacks are insufficient for your purposes, you can define your own. See Collection Customization and Defining Custom Collection Callbacks for more on this subject.
Except for trees (which are not true containers of other objects), collections come in two "flavors" or variants: immutable and mutable. The values in immutable collections are set for the life of the collection; you cannot add values to them or remove values from them. Mutable collections, however, let you add values, reorder values, and remove values. Mutable collections have two subflavors, fixed-size and variable-size, as determined by the capacity parameter in the functions that create these objects. For fixed-size collections you set the maximum number of values that the collection can contain. Variable-size collections, on the other hand, can hold an unlimited number of values (or rather, limited only by constraints external to the collection, like the amount of available memory). Fixed-size collections tend to be higher performing, but you must be able to put a definite limit on the number of values that can be contained.
Some Collection Services functions operate on both mutable and immutable collections (for example, getting the number of data elements and accessing data) whereas others work only with mutable collection objects, performing such operations as appending, inserting, removing, and sorting elements. See Working With Mutable Collections for details on these kinds of operations.
One type of function that is particularly interesting is the
applier function
. Most Collection Services types allow you to define a callback function. You then pass a pointer to this applier function in Collection Services functions that have
ApplyFunction
embedded in their names. The behavior defined in the callback function is applied iteratively to each element in the collection. This behavior is essentially the same thing as a
for
loop enumerating a collection; the code within the loop is applied to each element in the collection.