在iOS的后台线程中绘图
我有一些非常复杂的绘图逻辑(它是从GIS数据绘制的地图视图)的视图。在主线程中执行此绘图会锁定UI并使应用程序无响应。我想将绘图移动到后台线程,例如NSOperation。在iOS的后台线程中绘图
这种结构的最佳方式是什么?
我目前正在绘制一个关闭内存CGContext,然后将其转换为一个CGImageRef,我发送到视图blit主线程上。不幸的是,这消耗了大量的内存,看起来GPU加速已经不再使用,因为它比较慢。有没有从后台线程直接绘制视图的方法?我知道UIKit不是多线程安全的,但在绘图时可能有某种方式来锁定视图?
我从来没有遇到这种情况在iPhone上,但在Mac上我有类似的问题一次。
- 使用CGLayer委托脱机上下文的绘图活动。
- 尝试为当前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]];
}
这应该做的伎俩。
还尝试对您的进程进行采样并检查谁在使用CPU。这将使UI响应速度非常快。
您提到的性能问题可能是由于其他原因。尝试cpu示例过程。它会让你了解谁在实际使用CPU。
超越iOS 4.0,drawing is thread safe。您可能需要自己创建一个CGContext
,但没有理由不能在后台线程上绘制。
也就是说,大多数UIKit操作都不是。如果你需要这样做,你可以随时准备后台线程,然后在需要时使用performOnMainThread
。甚至还有waitUntilDone
。这就是说,显然你应该使用NSOperation
和NSOperationQueue
。
似乎有很多这方面的困惑,但这是正确的答案,因为iOS 4.0的UIKit绘图是线程安全的。这是官方公告:http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html(搜索“线程”)。 –
@Jon Tirsen,感谢你帮助证实了答案。 –
你的意思是CALayer? –
编号CGLayer。 http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGLayer/Reference/reference.html – MacGeek
所以我现在正在尝试这种方法,但即使我运行NSTimer并只运行50%的时间(以0.2s间隔运行,每个绘图周期最多0.1s),它似乎仍然忽略了所有UI事件。这有什么窍门吗? –