在iOS上的后台线程中绘图

时间:2011-10-09 07:19:27

标签: ios multithreading uikit core-graphics nsoperation

我有一个非常复杂的绘图逻辑视图(它是一个从GIS数据中提取的地图视图)。在主线程上执行此绘图会锁定UI并使应用程序无响应。我想将绘图移到背景线程,例如NSOperation。

构建这个的最佳方法是什么?

我正在绘制一个关闭内存的CGContext,然后将其转换为CGImageRef,我将其发送到视图以在主线程上进行blit。不幸的是,这会占用大量内存,似乎不再使用GPU加速,因为它的速度要慢得多。有没有从后台线程直接绘制到视图的方法?我知道UIKit不是多线程安全的,但是在我进行绘图时可能有一些方法可以锁定视图吗?

2 个答案:

答案 0 :(得分:6)

超越iOS 4.0,drawing is thread safe。您可能需要自己创建CGContext,但没有理由不能在后台线程上绘图。

也就是说,大多数UIKit的操作都没有。如果您需要这样做,您可以随时在后台线程中进行准备,然后在需要时使用performOnMainThread。甚至有waitUntilDone。也就是说,显然应该使用NSOperationNSOperationQueue

答案 1 :(得分:1)

我从未在iPhone上遇到过这样的情况,但在Mac上我曾遇到过类似的问题。

  1. 使用CGLayer委派离线上下文的绘图活动。
  2. 尝试为当前NSRunLoop添加计时器,并按照定时间隔执行图形命令。看起来应该是这样......
  3. ...

    kRenderFPS 25.0 //This is Maximum value
    
    renderTimer = [[NSTimer timerWithTimeInterval:(1.0 / (NSTimeInterval)kRenderFPS) target:viewobject selector:@selector(RenderUI:) userInfo:nil repeats:YES] retain];
    
    
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSDefaultRunLoopMode];
    
    
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSModalPanelRunLoopMode];
    
    
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSEventTrackingRunLoopMode];
    
    //In view class
    -(void)RenderUI:(id)param
    {
        [self setNeedsDisplayInRect:[self bounds]];
    }
    

    这应该可以解决问题。

    还尝试对您的流程进行采样并检查谁在消耗CPU。这将使UI响应迅速。

    您提到的性能问题可能是由于其他原因造成的。尝试cpu示例流程。它将让您了解谁实际上正在使用CPU。