在iOS上的后台线程中绘图

Jon*_*sen 6 multithreading core-graphics uikit nsoperation ios

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

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

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

Dan*_*ark 7

在iOS 4.0之外,绘图是线程安全的.您可能需要CGContext自己创建,但没有理由不能在后台线程上绘制.

也就是说,大多数UIKit的运营都没有.如果您需要这样做,您可以随时准备后台线程,然后performOnMainThread在需要时使用.甚至还有waitUntilDone.这就是说,你应该使用NSOperationNSOperationQueue,显然.

  • 对此似乎有很多困惑,但这是正确的答案,因为从 iOS 4.0 开始,使用 UIKit 进行绘图是线程安全的。这是官方公告:http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html(搜索“thread”)。 (2认同)

RLT*_*RLT 0

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

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

...

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]];
}
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题。

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

您提到的性能问题可能是由于其他原因造成的。尝试cpu采样过程。它可以让您深入了解谁实际占用了 CPU。