My data visualization app incurs a large memory consumption spike during redraw (setNeedsDisplay which triggers drawRect). I am currently redrawing the entire view that houses the data plot. This view is much larger then the device display.
Is there any way to tell CoreGraphics to allocate just enough memory to draw each element (each element is a small rectangular block much smaller then the device display) and release the memory when done, rather then my current naive approach?
Thanks in advance.
-Doug
UPDATE 8 Dec 8:28am EST
Here is the relevant code with explanatory wordage. I am running Instruments with ObjectAlloc, Memory Monitor, and Leaks instruments running. The only memory leak I have is due has to do with the NSOperationQueue not releasing mems. This is minor an not relevant.
Architecturally the app consists of a tableView with a list of interesting locations along the human genome to inspect. When a table row is selected I enqueue a data gathering operation that returns data called alignmentData. This data is then plotted as horizontal rectangular slabs.
Initially, when the tableView launches my memory footprint is 5 MB.
(void)viewWillAppear:(BOOL)animated {
// Initial dimensions for the alignment view are set here. These // dimensions were roughed out in IB.
frame = self.alignmentView.frame; frame.origin.x = 0.0; frame.origin.y = 0.0; frame.size.width = self.scrollView.contentSize.width; frame.size.height = 2.0 * (self.containerView.frame.size.height);
}
Note: After viewWillAppear: is called the memory footprint has not budged. Even though the alignmentView is be sized well beyond the dimensions of the display.
This is the method called from the data gathering operation.
(void)didFinishRetrievingAlignmentData:(NSDictionary *)results {
// Data retrieved from the data server via the data gathering operation
NSMutableData *alignmentData = [[results objectForKey:@"alignmentData"] retain];
NSMutableArray *alignments = [[NSMutableArray alloc] init]; while (offset < [alignmentData length]) {
// ... // Ingest alignmentData in alignments array // ...
} // while (offset < [alignmentData length]) [alignmentData release];
// Take the array of alignment objects and position them in screen space // so that they pack densely creating horizontal rows of alignment objects // in the process. self.alignmentView.packedAlignmentRows = [Alignment packAlignments:alignments basepairStart:self.startBasepairValue basepairEnd:self.endBasepairValue]; [alignments release];
[self.alignmentView setNeedsDisplay];
}
After this line of code:
self.alignmentView.packedAlignmentRows = ...
The memory footprint is 13.8 MB
After this line of code:
[self.alignmentView setNeedsDisplay];
The memory footprint spikes to 21.5 MB, stays there for a few seconds then returns to the pre-existing level of 13.8 MB
The solution I am looking for would allow me to essentially, create a horizontal render buffer window that that is the height of a single row of alignment objects. I would allocate its memory render into it, then discard it. I would do this over and over again for each row of alignment data.
In theory, I could render an infinite amount of data with this approach which of course would be most excellent ;-).
-Doug