Some types accept create-time messages not only when creating a new instance, but to customize a new version of the type itself. Objects created from a customized type will have all options preset that create-time messages sent to the customized type object have already set. If many objects all need the same create-time options, it is often simpler (and can also be faster) to create a customized version of a type first, and then create further instances from that type.
Customizing a type object does not modify the original type object, but instead creates a new type object that has the customizations built-in. A create: message on the new type object creates a new instance as if the same sequence of create-time messages had been sent to the original type object using createBegin: and createEnd. A type is customized by bracketing the sequence of create-time messages not with the createBegin: and createEnd messages used to create a new instance, but with customizeBegin: and customizeEnd messages instead.
Whether a customized version of a type can be created depends on the implementation of the type itself. If a type does not support customization, a customizeBegin: message on the type raises an error. All types defined by an @protocol declaration may be relied on to support at least one cycle of customization to create a new type object. Whether an already customized type object (returned by customizeEnd) supports a further cycle of customization (by another sequence of customizeBegin:/customizeEnd) depends on the implementation of the original starting type. A type should not be relied on to support more than one cycle of customization unless it is specifically documented to do so.
newArrayType1 = [Array customizeBegin: aZone]; [newArrayType1 setCount: 100]; newArrayType2 = [newArrayType2 customizeCopy: aZone]; [newArrayType2 setDefaultMember: UnsetMember]; newArrayType1 = [newArrayType1 customizeEnd]; newArrayType2 = [newArrayType2 customizeEnd]; array1 = [newArrayType1 create: aZone]; // no DefaultMember option array2 = [newArrayType create: aZone]; // DefaultMember option set