Вы можете переопределить alloc
или allocWithZone:
, как и любой другой метод класса. Необходимо выделить память для экземпляра и установить указатель isa
. Примерно так будет работать:
void *memoryPool;
void *nextObject;
+ (id) alloc;
{
id result = (id)nextObject;
size_t instanceSize = class_getInstanceSize( self );
nextObject += instanceSize;
memset( result, 0, instanceSize );
result->isa = self;
return result;
}
+ (id) allocWithZone: (NSZone *) zone;
{
return nil;
}
- (void) dealloc; { /* do nothing */ }
Каждый подкласс класса, реализующего эти методы, будет размещен в буфере на memoryPool
. При выделении буфера nextObject
должен быть установлен на тот же буфер. Когда вы закончите с этими объектами, вы можете освободить их все, освободив memoryPool
.
Обратите внимание, что это еще не идеально. Вам, вероятно, следует отслеживать местоположение каждого выделенного объекта, чтобы вы могли вызывать их dealloc
методы перед освобождением пула. Dealloc не может освободить память, используемую объектом, но может потребоваться освободить другие ресурсы.
Вам также необходимо убедиться, что у вас нет ссылок на объекты в вашем пуле, прежде чем вы его освободите.
Если вы ищете решение, которое позволит вам размещать объекты любого класса в пуле, как это, вам не повезло. Использование NSZone
с allocWithZone:
может помочь в увеличении скорости выделения, но нет способа освободить все объекты внутри зоны одновременно.
Но вам действительно следует делать это только после профилирования, если вы уверены, что выделение ваших объектов является проблемой производительности. Часто это не так.