Создание пользовательских средств выделения

Для создания пользовательского средства выделения сначала объявите и инициализируйте структуру типа CFAllocatorContext. Инициализируйте поле версии к 0 и выделите и присвойте любые желаемые данные, такие как управляющая информация, к info поле. Другие поля этой структуры являются указателями функции, описанными в Реализации Обратных вызовов Средства выделения, ниже.

Как только Вы присвоили собственные значения полям CFAllocatorContext структура, вызовите CFAllocatorCreate функция для создания объекта-распределителя. Второй параметр этой функции является указателем на структуру. Первый параметр этой функции идентифицирует средство выделения для использования для выделения памяти для нового объекта. Если Вы хотите использовать allocate обратный вызов в CFAllocateContext структура с этой целью, укажите kCFAllocatorUseContext постоянный для первого параметра. Если Вы хотите использовать средство выделения по умолчанию, указать NULL в этом параметре.

Перечисление 1  , Создающее пользовательское средство выделения

static CFAllocatorRef myAllocator(void) {
    static CFAllocatorRef allocator = NULL;
    if (!allocator) {
        CFAllocatorContext context =
            {0, NULL, NULL, (void *)free, NULL,
             myAlloc, myRealloc, myDealloc, NULL};
        context.info = malloc(sizeof(int));
        allocator = CFAllocatorCreate(NULL, &context);
    }
    return allocator;
}

Реализация обратных вызовов средства выделения

CFAllocatorContext структура имеет семь полей, определяющих функции обратного вызова. При создании пользовательского средства выделения, необходимо реализовать, по крайней мере, allocate функция. Обратные вызовы средства выделения должны быть ориентированы на многопотоковое исполнение и, если обратный вызов вызывает другие функции, они должны быть повторно используемы также.

Сохранение, выпуск и обратные вызовы описания копии все берут в качестве их отдельного аргумента info поле CFAllocatorContext структура. Введенный как void *, это поле указывает на любые данные, что Вы определяете для средства выделения, такого как структура, содержащая управляющую информацию.

Сохраните обратный вызов:

const void *(*retain)(const void *info);

Сохраните данные, в которых Вы определили для контекста средства выделения info. Это могло бы быть целесообразным, только если данные являются Базовым объектом Основы. Можно установить этот указатель функции в NULL.

Обратный вызов выпуска:

void (*release)(const void *info);

Выпуск (или свободный) данные Вы определили для контекста средства выделения. Можно установить этот указатель функции в NULL, но выполнение так могло бы привести к утечкам памяти.

Обратный вызов описания копии:

CFStringRef (*copyDescription)(const void *info);

Возвратите ссылку на CFString, описывающий Ваше средство выделения, особенно некоторые характеристики Ваших определяемых пользователем данных. Можно установить этот указатель функции в NULL, когда Базовая Основа предоставит элементарное описание.

Выделите обратный вызов:

void *   (*allocate)(CFIndex size, CFOptionFlags hint, void *info);

Выделите блок памяти, по крайней мере, size байты и возврат указатель на запуск блока. hint параметром является битовое поле, которое Вы не должны в настоящее время использовать. size параметр должен всегда быть больше, чем 0. Если это не, или если проблемы в выделении происходят, возвратиться NULL. Этот обратный вызов может не быть NULL.

Перераспределите обратный вызов:

void *   (*reallocate)(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info);

Измените размер блока памяти, которой указывают ptr к размеру, указанному newsize и возвратите указатель на больший блок памяти. Возвратиться NULL при любом отказе перераспределения, оставляя старый блок памяти нетронутым. Обратите внимание на то, что ptr параметр никогда не будет NULL, и newsize всегда будет больше, чем 0— этот обратный вызов не используется, если не удовлетворяют тем двум условиям.

Оставьте содержание старого блока памяти неизменным до меньших из новых или старых размеров. Если ptr параметр не является блоком памяти, ранее выделенной средством выделения, результаты не определены; аварийное завершение программы может произойти. hint параметром является битовое поле, которое Вы не должны в настоящее время использовать. Если Вы устанавливаете этот обратный вызов в NULL CFAllocatorReallocate функциональные возвраты NULL в большинстве случаев, когда это пытается использовать это средство выделения.

Освободите обратный вызов:

void   (*deallocate)(void *ptr, void *info);

Сделайте блок памяти указанным ptr доступный для последующего повторного использования средством выделения, но недоступный продолжительному использованию программой. ptr параметр не может быть NULL и если ptr параметр не является блоком памяти, ранее выделенной средством выделения, результаты не определены; аварийное завершение программы может произойти. Можно установить этот обратный вызов в NULL, когда CFAllocatorDeallocate функция не имеет никакого эффекта.

Предпочтительный обратный вызов размера:

CFIndex   (*preferredSize)(CFIndex size, CFOptionFlags hint, void *info);

Возвратите фактический размер, который средство выделения, вероятно, выделит данный запрос на блок памяти размера size. hint параметром является битовое поле, которое Вы не должны в настоящее время использовать.