It sounds like your NSImages are being added to the autorelease pool at some point. They won’t normally be flushed until the pool is drained.
In instances like this you want to make your own autorelease pool:
NSImage *outputImage = [[NSImage alloc] initWithSize:size];
[outputImage lockFocus];
while(1000 times) {
@autoreleasepool {
NSImage* image = [[NSImage alloc] initWithSize:size];
... image is processed ...
[image drawInRect: ... fromRect: ... ]
}
}
[outputImage unlockFocus];
This creates a sub-pool that will get drained on every pass, so you won’t have a huge build-up of images.