我正在构建一个光谱仪,想知道如何提高基于UIView
的代码的性能。我知道我无法从后台线程更新iPhone / iPad的用户界面,所以我正在使用GCD进行大部分处理。我遇到的问题是我的界面仍然更新速度太慢。
使用下面的代码,我尝试采用32个堆叠的4x4像素UIView
并更改其背景颜色(请参阅附加图像上的绿色方块)。该操作为其他用户界面产生可见的延迟。
有没有办法可以从某种后台线程“准备”这些颜色,然后让主线程一次刷新界面?
//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];
}
我最终预先计算了256种颜色的字典,然后根据圆圈试图显示的值向字典询问颜色。试图在运行中分配颜色是瓶颈。
答案 0 :(得分:1)
,是的,有几点。
虽然您不应该在主线程上处理UIView,但您可以在使用它们之前在后台线程上实例化视图。不确定这对你是否有帮助。然而,除了在后台线程上实例化视图之外,UIView实际上只是CALayer对象的元数据包装器,并且针对灵活性而非性能进行了优化。
最好的办法是在背景线程上绘制图层对象或图像对象(这是一个较慢的过程,因为绘图使用CPU和GPU),将图层对象或图像传递给主线程,然后将预渲染的图像绘制到视图的图层(速度要快得多,因为可以通过简单的调用让图形处理器直接将图像blit到UIView的后备存储区。)
看到这个答案:
Render to bitmap then blit to screen
代码:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, rect, image);
}
的执行速度比在同一方法中执行其他绘图操作(如绘制贝塞尔曲线)要快得多。