So I have some code running in an NSThread
that creates, in a loop, a whole bunch of NSImage
s. A small section of each of the images is drawn into another NSImage
, and then the thread exits.
So, something like
NSImage *outputImage = [[NSImage alloc] initWithSize:size];
[outputImage lockFocus];
while(1000 times)
NSImage* image = [[NSImage alloc] initWithSize:size];
... image is processed ...
[image drawInRect: ... fromRect: ... ]
[outputImage unlockFocus];
Once this is complete, the thread uses performSelectorOnMainThread
to send the created NSImage back to the main thread to have it placed in a view.
This all works fine, and the final image is exactly as I expect it to be. However, during the loop the memory usage of the application rises linearly - as though each NSImage
isn't released until some later time. My theory is that the drawInRect
calls are being pipelined somewhere and not actually executed until later. Is this correct? And if so how do I prevent it? My application will crash if I make my loop counter too large at the moment, and I'd like to avoid that.
I've tried moving the locking and unlocking of focus into the loop, but this made no difference.
I've confirmed that if I take out only the drawInRect
call, the memory usage is (more or less) flat for the lifetime of the thread. It's only when I put the call in that the memory climbs.
I'm (obviously?) using ARC in this project, and it's running in OSX10.9.
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:
This creates a sub-pool that will get drained on every pass, so you won’t have a huge build-up of images.