I'm building a spectrograph and would like to know how I can improve the performance of my UIView
-based code. I know that I cannot update user interface for iPhone/iPad from a background thread, so I'm doing most of my processing using GCD. The issue that I'm running into is that my interface still updates way too slowly.
With the code below, I'm trying to take 32 stacked 4x4 pixel UIView
s and change their background color (see the green squares on the attached image). The operation produces visible lag for other user interface.
Is there a way I can "prepare" these colors from some kind of background thread and then ask the main thread to refresh the interface all at once?
//create a color intensity map used to color pixels
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
colorMap = [[NSMutableDictionary alloc] initWithCapacity:128];
for(int i = 0; i<128; i ++)
{
[colorMap setObject:[UIColor colorWithHue:0.2 saturation:1 brightness:i/128.0 alpha:1] forKey:[NSNumber numberWithInt:i]];
}
});
-(void)updateLayoutFromMainThread:(id)sender
{
for(UIView* tempView in self.markerViews)
{
tempView.backgroundColor =[colorMap objectForKey:[NSNumber numberWithInt:arc4random()%128]];
}
}
//called from background, would do heavy processing and fourier transforms
-(void)updateLayout
{
//update the interface from the main thread
[self performSelectorOnMainThread:@selector(updateLayoutFromMainThread:) withObject:nil waitUntilDone:NO];
}
I ended up pre-calculating a dictionary of 256 colors and then asking the dictionary for the color based on the value that the circle is trying to display. Trying to allocate colors on the fly was the bottleneck.