views:

48

answers:

1

In C and C++ i use the popular memory pool allocator. Where a huge chunk of memory is allocated and then all small objects are allocated inside it. When done everything is freed with a single call. I was able to speed up some bottlenecks my app by factor 10.

Question is how can i do this with Cocoa?

How can i overwrite the alloc method?

+2  A: 

You can override alloc or allocWithZone: like any other class method. It needs to allocate memory for the instance and set the isa pointer. Something like this would work:

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 */ }

Every subclass of a class implementing those methods would be allocated into the buffer at memoryPool. When allocating the buffer nextObject has to be set to the same buffer. When you are done with those objects you can deallocate all of them by freeing memoryPool.

Note that this is not perfect yet. You probably should track the locations of every single allocated object so you can call their dealloc methods before freeing the pool. Dealloc cannot free the memory used by the object, but it might be needed to release other resources.

You also need to make sure that you don’t have any references to objects in your pool before you free it.

If you are looking for a solution that allows you to allocate objects of any class in a pool like this you are out of luck. Using a NSZone with allocWithZone: might help with allocation speed, but there is no way to free all objects inside of a zone at once.

But you really should do this only after profiling if you are sure your object allocations are a performance problem. Often they are not.

Sven
+1 for profiling suggestion.
Joshua Nozzi