Создание пользовательских средств выделения
Для создания пользовательского средства выделения сначала объявите и инициализируйте структуру типа 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
параметром является битовое поле, которое Вы не должны в настоящее время использовать.